diff --git a/doc/system_description/software.md b/doc/system_description/software.md index 8d0dde6..99b23c2 100644 --- a/doc/system_description/software.md +++ b/doc/system_description/software.md @@ -532,5 +532,7 @@ Assigned core prefixes: | `BLAKE2S` | r/w | r | 4B | u32 | | Function pointer to a BLAKE2S function in the firmware | | `CDI_FIRST` | r/w | r | 32B | u8[32] | | Compound Device Identifier (CDI). UDS+measurement... | | `CDI_LAST` | | r | | | | Last word of CDI | +| `RAM_ASLR` | w | invisible | 4B | u32 | | Address Space Randomization seed value for the RAM | +| `RAM_SCRAMBLE` | w | invisible | 4B | u32 | | Data scrambling seed value for the RAM | [^3]: The UDS can only be read *once* per power-cycle. diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index 5feb581..2432ee3 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -25,6 +25,9 @@ module tk1( input wire cpu_valid, output wire force_trap, + output wire [14 : 0] ram_aslr, + output wire [31 : 0] ram_scramble, + output wire led_r, output wire led_g, output wire led_b, @@ -36,7 +39,6 @@ module tk1( input wire cs, input wire we, - input wire [7 : 0] address, input wire [31 : 0] write_data, output wire [31 : 0] read_data, @@ -47,41 +49,45 @@ module tk1( //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - localparam ADDR_NAME0 = 8'h00; - localparam ADDR_NAME1 = 8'h01; - localparam ADDR_VERSION = 8'h02; + localparam ADDR_NAME0 = 8'h00; + localparam ADDR_NAME1 = 8'h01; + localparam ADDR_VERSION = 8'h02; - localparam ADDR_SWITCH_APP = 8'h08; + localparam ADDR_SWITCH_APP = 8'h08; - localparam ADDR_LED = 8'h09; - localparam LED_R_BIT = 2; - localparam LED_G_BIT = 1; - localparam LED_B_BIT = 0; + localparam ADDR_LED = 8'h09; + localparam LED_R_BIT = 2; + localparam LED_G_BIT = 1; + localparam LED_B_BIT = 0; - localparam ADDR_GPIO = 8'h0a; - localparam GPIO1_BIT = 0; - localparam GPIO2_BIT = 1; - localparam GPIO3_BIT = 2; - localparam GPIO4_BIT = 3; + localparam ADDR_GPIO = 8'h0a; + localparam GPIO1_BIT = 0; + localparam GPIO2_BIT = 1; + localparam GPIO3_BIT = 2; + localparam GPIO4_BIT = 3; - localparam ADDR_APP_START = 8'h0c; - localparam ADDR_APP_SIZE = 8'h0d; + localparam ADDR_APP_START = 8'h0c; + localparam ADDR_APP_SIZE = 8'h0d; - localparam ADDR_BLAKE2S = 8'h10; + localparam ADDR_BLAKE2S = 8'h10; - localparam ADDR_CDI_FIRST = 8'h20; - localparam ADDR_CDI_LAST = 8'h27; + localparam ADDR_CDI_FIRST = 8'h20; + localparam ADDR_CDI_LAST = 8'h27; - localparam ADDR_UDI_FIRST = 8'h30; - localparam ADDR_UDI_LAST = 8'h31; + localparam ADDR_UDI_FIRST = 8'h30; + localparam ADDR_UDI_LAST = 8'h31; + + localparam ADDR_RAM_ASLR = 8'h40; + localparam ADDR_RAM_SCRAMBLE = 8'h41; localparam ADDR_CPU_MON_CTRL = 8'h60; localparam ADDR_CPU_MON_FIRST = 8'h61; localparam ADDR_CPU_MON_LAST = 8'h62; - localparam TK1_NAME0 = 32'h746B3120; // "tk1 " - localparam TK1_NAME1 = 32'h6d6b6466; // "mkdf" - localparam TK1_VERSION = 32'h00000004; + + localparam TK1_NAME0 = 32'h746B3120; // "tk1 " + localparam TK1_NAME1 = 32'h6d6b6466; // "mkdf" + localparam TK1_VERSION = 32'h00000004; localparam FW_RAM_FIRST = 32'hd0000000; localparam FW_RAM_LAST = 32'hd00003ff; @@ -124,6 +130,11 @@ module tk1( reg [2 : 0] cpu_trap_led_new; reg cpu_trap_led_we; + reg [14 : 0] ram_aslr_reg; + reg ram_aslr_we; + reg [31 : 0] ram_scramble_reg; + reg ram_scramble_we; + reg cpu_mon_en_reg; reg cpu_mon_en_we; reg [31 : 0] cpu_mon_first_reg; @@ -157,6 +168,9 @@ module tk1( assign gpio3 = gpio3_reg; assign gpio4 = gpio4_reg; + assign ram_aslr = ram_aslr_reg; + assign ram_scramble = ram_scramble_reg; + //---------------------------------------------------------------- // Module instance. @@ -208,6 +222,8 @@ module tk1( cpu_mon_en_reg <= 1'h0; cpu_mon_first_reg <= 32'h0; cpu_mon_last_reg <= 32'h0; + ram_aslr_reg <= 15'h0; + ram_scramble_reg <= 32'h0; end else begin @@ -251,6 +267,14 @@ module tk1( cdi_mem[address[2 : 0]] <= write_data; end + if (ram_aslr_we) begin + ram_aslr_reg <= write_data[14 : 0]; + end + + if (ram_scramble_we) begin + ram_scramble_reg <= write_data; + end + if (cpu_trap_led_we) begin cpu_trap_led_reg <= cpu_trap_led_new; end @@ -330,6 +354,8 @@ module tk1( blake2s_addr_we = 1'h0; cdi_mem_we = 1'h0; cdi_mem_we = 1'h0; + ram_aslr_we = 1'h0; + ram_scramble_we = 1'h0; cpu_mon_en_we = 1'h0; cpu_mon_first_we = 1'h0; cpu_mon_last_we = 1'h0; @@ -377,6 +403,18 @@ module tk1( end end + if (address == ADDR_RAM_ASLR) begin + if (!switch_app_reg) begin + ram_aslr_we = 1'h1; + end + end + + if (address == ADDR_RAM_SCRAMBLE) begin + if (!switch_app_reg) begin + ram_scramble_we = 1'h1; + end + end + if (address == ADDR_CPU_MON_CTRL) begin cpu_mon_en_we = 1'h1; end diff --git a/hw/application_fpga/fw/tk1_mem.h b/hw/application_fpga/fw/tk1_mem.h index 0d53d78..ff0090d 100644 --- a/hw/application_fpga/fw/tk1_mem.h +++ b/hw/application_fpga/fw/tk1_mem.h @@ -93,6 +93,8 @@ enum { TK1_MMIO_TK1_CDI_LAST = TK1_MMIO_TK1_BASE | 0x9c, // Address of last 32-bit word of CDI. TK1_MMIO_TK1_UDI_FIRST = TK1_MMIO_TK1_BASE | 0xc0, TK1_MMIO_TK1_UDI_LAST = TK1_MMIO_TK1_BASE | 0xc4, // Address of last 32-bit word of UDI. + TK1_MMIO_TK1_RAM_ASLR = TK1_MMIO_TK1_BASE | 0x100, + TK1_MMIO_TK1_RAM_SCRAMBLE = TK1_MMIO_TK1_BASE | 0x104, TK1_MMIO_TK1_CPU_MON_CTRL = TK1_MMIO_TK1_BASE | 0x180, TK1_MMIO_TK1_CPU_MON_FIRST = TK1_MMIO_TK1_BASE | 0x184, TK1_MMIO_TK1_CPU_MON_LAST = TK1_MMIO_TK1_BASE | 0x188, diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index b7600b2..e6506a8 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -155,6 +155,8 @@ module application_fpga( wire tk1_ready; wire fw_app_mode; wire force_trap; + wire [14 : 0] ram_aslr; + wire [31 : 0] ram_scramble; //---------------------------------------------------------------- @@ -316,14 +318,17 @@ module application_fpga( .clk(clk), .reset_n(reset_n), - .cpu_trap(cpu_trap), .fw_app_mode(fw_app_mode), .cpu_addr(cpu_addr), .cpu_instr(cpu_instr), .cpu_valid(cpu_valid), + .cpu_trap(cpu_trap), .force_trap(force_trap), + .ram_aslr(ram_aslr), + .ram_scramble(ram_scramble), + .led_r(led_r), .led_g(led_g), .led_b(led_b), @@ -380,8 +385,8 @@ module application_fpga( ram_cs = 1'h0; ram_we = cpu_wstrb; - ram_address = cpu_addr[16 : 2]; - ram_write_data = cpu_wdata; + ram_address = cpu_addr[16 : 2] ^ ram_aslr; + ram_write_data = cpu_wdata ^ ram_scramble ^ {2{cpu_addr[15 : 0]}}; fw_ram_cs = 1'h0; fw_ram_we = cpu_wstrb; @@ -430,7 +435,7 @@ module application_fpga( RAM_PREFIX: begin ram_cs = 1'h1; - muxed_rdata_new = ram_read_data; + muxed_rdata_new = ram_read_data ^ ram_scramble ^ {2{cpu_addr[15 : 0]}}; muxed_ready_new = ram_ready; end