blob: b1be5e6157aba751e0a2fa5bd69cd3f56aa22ff5 [file] [log] [blame] [view]
Hugo McNallyf6298b32023-02-12 14:47:22 +00001# SRAM Controller Technical Specification
Michael Schaffner86c0e322020-10-07 19:56:32 -07002
3
4# Overview
5
6This document specifies the functionality of the SRAM memory controller.
Hugo McNallyaef0a662023-02-11 19:44:55 +00007The SRAM controller is a module that is a peripheral on the chip interconnect bus, and thus follows the [Comportability Specification](../../../doc/contributing/hw/comportability/README.md).
Michael Schaffner86c0e322020-10-07 19:56:32 -07008
9
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070010The SRAM controller contains the SRAM data and address scrambling device and provides CSRs for requesting the scrambling keys and triggering the hardware initialization feature.
Michael Schaffner86c0e322020-10-07 19:56:32 -070011
12## Features
13
Hugo McNallyaef0a662023-02-11 19:44:55 +000014- [Lightweight scrambling mechanism](../prim/doc/prim_ram_1p_scr.md#custom-substitution-permutation-network) based on the PRINCE prince cipher.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -080015- Key request logic for the lightweight memory and address scrambling device.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070016- Alert sender and checking logic for detecting bus integrity failures.
17- LFSR-based memory initialization feature.
18- Access controls to allow / disallow code execution from SRAM.
Timothy Chen12cce142021-03-02 18:11:01 -080019- Security hardening when integrity error has been detected.
Michael Schaffner86c0e322020-10-07 19:56:32 -070020
21# Theory of Operations
22
Michael Schaffnera3bedf52020-12-03 20:22:10 -080023## Block Diagram
Michael Schaffner86c0e322020-10-07 19:56:32 -070024
Hugo McNallyaef0a662023-02-11 19:44:55 +000025![SRAM Controller Block Diagram](./doc/sram_ctrl_blockdiag.svg)
Michael Schaffner86c0e322020-10-07 19:56:32 -070026
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070027As shown in the block diagram above, the SRAM controller contains a TL-UL adapter, an initialization LFSR, the CSR node, key request logic and an instance of `prim_ram_1p_scr` that implements the actual scrambling mechanism.
Michael Schaffnera3bedf52020-12-03 20:22:10 -080028
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070029The SRAM controller supports the system-wide end-to-end bus integrity scheme and thus stores the data integrity bits alongside each data word in the memory.
30I.e., this means that both the 32 data bits and 7 integrity bits are passed through the scrambling device.
31
32Sub-word write operations therefore perform a read-modify-write operation in order to ensure consistency of the integrity bits.
33Hence, the throughput of sub-word write operations is three times lower than for full-word write operations.
34Note however that the throughput of read operations is the same for full- and sub-word read operations.
35
36The scrambling mechanism is always enabled and the `sram_ctrl` provides the scrambling device with a predefined scrambling key and nonce when it comes out of reset.
Hugo McNally544e7a62023-02-12 01:12:36 +000037It is the task of SW to request an updated scrambling key and nonce via the CSRs as described in the [Programmer's Guide](#programmers-guide) below.
Michael Schaffnera3bedf52020-12-03 20:22:10 -080038
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070039For SW convenience, the SRAM controller also provides an LFSR-based memory initialization feature that can overwrite the entire memory with pseudorandom data.
Hugo McNally544e7a62023-02-12 01:12:36 +000040Similarly to the scrambling key, it is the task of of SW to request memory initialization via the CSRs as described in the [Programmer's Guide](#programmers-guide) below.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070041
42Note that TL-UL accesses to the memory that occur while a key request or hardware initialization is pending will be blocked until the request has completed.
43
44The individual mechanisms are explained in more detail in the subsections below.
Michael Schaffnera3bedf52020-12-03 20:22:10 -080045
Michael Schaffner86c0e322020-10-07 19:56:32 -070046## Hardware Interfaces
47
48### Parameters
49
50The following table lists the instantiation parameters of the SRAM controller.
51
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070052Parameter | Default | Top Earlgrey | Description
53----------------------------|-----------------------|-------------------|---------------
54`AlertAsyncOn` | 1'b1 | 1'b1 |
55`InstrExec` | 1 | 1 | Enables the execute from SRAM feature.
56`MemSizeRam` | 4096 | (multiple values) | Number of 32bit words in the SRAM (can be overridden by `topgen`).
57`RndCnstSramKey` | (see RTL) | (see RTL) | Compile-time random default constant for scrambling key.
58`RndCnstSramNonce` | (see RTL) | (see RTL) | Compile-time random default constant for scrambling nonce.
59`RndCnstLfsrSeed` | (see RTL) | (see RTL) | Compile-time random default constant for LFSR seed.
60`RndCnstLfsrPerm` | (see RTL) | (see RTL) | Compile-time random default constant for LFSR permutation.
Michael Schaffner86c0e322020-10-07 19:56:32 -070061
62### Signals
63
Hugo McNallyba16bae2023-02-12 21:08:04 +000064* [Interface Tables](data/sram_ctrl.hjson#interfaces)
Michael Schaffner86c0e322020-10-07 19:56:32 -070065
66The table below lists other SRAM controller signals.
67
68Signal | Direction | Type | Description
69---------------------------|------------------|------------------------------------|---------------
Michael Schaffner0a796782022-02-15 13:54:53 -080070`lc_hw_debug_en_i` | `input` | `lc_ctrl_pkg::lc_tx_t` | Multibit life cycle hardware debug enable signal coming from life cycle controller, asserted when the hardware debug mechanisms are enabled in the system.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070071`lc_escalate_en_i` | `input` | `lc_ctrl_pkg::lc_tx_t` | Multibit life cycle escalation enable signal coming from life cycle controller, asserted if an escalation has occurred.
Michael Schaffnera3bedf52020-12-03 20:22:10 -080072`sram_otp_key_o` | `output` | `otp_ctrl_pkg::sram_otp_key_req_t` | Key derivation request going to the key derivation interface of the OTP controller.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070073`sram_otp_key_i` | `input` | `otp_ctrl_pkg::sram_otp_key_rsp_t` | Ephemeral scrambling key coming back from the key derivation interface of the OTP controller.
Hugo McNally6321c5e2023-02-16 21:39:55 +000074`otp_en_sram_ifetch_i` | `input` | `otp_ctrl_pkg::mubi8_t` | Multibit value coming from the OTP HW_CFG partition ([EN_SRAM_IFETCH](../otp_ctrl/README.md#direct-access-memory-map)), set to kMuBi8True in order to enable the [`EXEC`](data/sram_ctrl.hjson#exec) CSR.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070075`cfg_i` | `input` | `logic [CfgWidth-1:0]` | Attributes for physical memory macro.
Michael Schaffner86c0e322020-10-07 19:56:32 -070076
Michael Schaffner9a1bfee2020-12-21 19:21:25 -080077#### Interfaces to OTP and the SRAM Scrambling Primitive
Michael Schaffner86c0e322020-10-07 19:56:32 -070078
Michael Schaffnere19d8722022-01-21 22:14:01 -080079The interface to the key derivation interface inside the OTP controller follows a simple req / ack protocol, where the SRAM controller first requests an updated ephemeral key by asserting the `sram_otp_key_i.req`.
Hugo McNallyaef0a662023-02-11 19:44:55 +000080The OTP controller then fetches entropy from CSRNG and derives an ephemeral key using the SRAM_DATA_KEY_SEED and the PRESENT scrambling data path as described in the [OTP controller spec](../otp_ctrl/README.md#scrambling-datapath).
Michael Schaffner86c0e322020-10-07 19:56:32 -070081Finally, the OTP controller returns a fresh ephemeral key via the response channels (`sram_otp_key_o[*]`, `otbn_otp_key_o`), which complete the req / ack handshake.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070082The key and nonce are made available to the scrambling primitive in the subsequent cycle.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -080083The wave diagram below illustrates this process.
Michael Schaffner86c0e322020-10-07 19:56:32 -070084
Hugo McNallyc641c582023-02-12 22:49:10 +000085```wavejson
Michael Schaffner86c0e322020-10-07 19:56:32 -070086{signal: [
Michael Schaffner9a1bfee2020-12-21 19:21:25 -080087 {name: 'clk_otp_i', wave: 'p...........'},
88 {name: 'sram_otp_key_o.req', wave: '0.|1.|..0|..'},
89 {name: 'sram_otp_key_i.ack', wave: '0.|..|.10|..'},
90 {name: 'sram_otp_key_i.nonce', wave: '0.|..|.30|..'},
91 {name: 'sram_otp_key_i.key', wave: '0.|..|.30|..'},
92 {name: 'sram_otp_key_i.seed_valid', wave: '0.|..|.10|..'},
93 {},
94 {name: 'clk_i', wave: 'p...........'},
Michael Schaffnerc89d9d92021-07-27 18:24:33 -070095 {name: 'key_valid_q', wave: '10|..|...|1.'},
96 {name: 'key_q', wave: '4.|..|...|3.'},
97 {name: 'nonce_q', wave: '4.|..|...|3.'},
98 {name: 'key_seed_valid_q', wave: '4.|..|...|3.'},
Michael Schaffner86c0e322020-10-07 19:56:32 -070099]}
Hugo McNallyc641c582023-02-12 22:49:10 +0000100```
Michael Schaffner86c0e322020-10-07 19:56:32 -0700101
102If the key seeds have not yet been provisioned in OTP, the keys are derived from all-zero constants, and the `*.seed_valid` signal will be set to 0 in the response.
103It should be noted that this mechanism requires the CSRNG and entropy distribution network to be operational, and a key derivation request will block if they are not.
104
105Note that the req/ack protocol runs on `clk_otp_i`.
106The SRAM controller synchronizes the data over via a req/ack handshake primitive `prim_sync_reqack.sv` primitive as shown below.
107
Hugo McNallyaef0a662023-02-11 19:44:55 +0000108![OTP Key Req Ack](../otp_ctrl/doc/otp_ctrl_key_req_ack.svg)
Michael Schaffner86c0e322020-10-07 19:56:32 -0700109
110Note that the key and nonce output signals on the OTP controller side are guaranteed to remain stable for at least 62 OTP clock cycles after the `ack` signal is pulsed high, because the derivation of a 64bit half-key takes at least two passes through the 31-cycle PRESENT primitive.
111Hence, if the SRAM controller clock `clk_i` is faster or in the same order of magnitude as `clk_otp_i`, the data can be directly sampled upon assertion of `src_ack_o`.
112If the SRAM controller runs on a significantly slower clock than OTP, an additional register (as indicated with dashed grey lines in the figure) has to be added.
113
Michael Schaffnerd1364a42022-02-23 17:19:46 -0800114#### Global and Local Escalation
Michael Schaffner86c0e322020-10-07 19:56:32 -0700115
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800116If `lc_escalate_en_i` is set to any different value than `lc_ctrl_pkg::Off`, the current scrambling keys are discarded and reset to `RndCnstSramKey` and `RndCnstSramNonce` in the subsequent cycle.
117Any subsequent memory request to `prim_ram_1p_scr` will then be blocked as well.
Hugo McNallyaef0a662023-02-11 19:44:55 +0000118This mechanism is part of the [life cycle](../lc_ctrl/README.md) state scrapping and secret wiping countermeasure triggered by the alert handler (global escalation).
Michael Schaffnerd1364a42022-02-23 17:19:46 -0800119
120Note that if any local bus integrity or counter errors are detected, the SRAM controller will locally escalate without assertion of `lc_escalate_en_i`.
121The behavior of local escalation is identical to global escalation via `lc_escalate_en_i`.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800122
123## Scrambling Primitive
124
Hugo McNallyaef0a662023-02-11 19:44:55 +0000125As explained in [`prim_ram_1p_scr`](../prim/doc/prim_ram_1p_scr.md) the scrambling mechanism employs a reduced-round PRINCE block cipher in CTR mode to scramble the data.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700126Since plain CTR mode does not diffuse the data bits due to the bitwise XOR, the scheme is augmented by passing each word through a shallow substitution-permutation (S&P) network implemented with the `prim_subst_perm` primitive.
Hugo McNallyaef0a662023-02-11 19:44:55 +0000127The S&P network employed is similar to the one employed in PRESENT and is explained in more detail [here](../prim/doc/prim_ram_1p_scr.md#custom-substitution-permutation-network).
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800128
129Another CTR mode augmentation that is aimed at breaking the linear address space is SRAM address scrambling.
Michael Schaffnere19d8722022-01-21 22:14:01 -0800130The same S&P network construction that is used for intra-word diffusion is leveraged to non-linearly remap the SRAM address as shown in the block diagram above.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800131
Timothy Chen12cce142021-03-02 18:11:01 -0800132### Integrity Error Handling
133
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700134When an integrity error is encountered, the `sram_ctrl` will latch the integrity error send out a `fatal_bus_integ_error` until the next reset (the generation of the integrity error is determined by system integration).
135In addition, the latched error condition is fed into the `prim_ram_1p_scr` primitive via a dedicated input, causing the scrambling primitive to do the following:
Timothy Chen12cce142021-03-02 18:11:01 -0800136* Reverse the nonce used during the address and CTR scrambling.
137* Disallow any transaction (read or write) on the actual memory macro.
138
139This behavior, combined with other top level defenses, form a multi-layered defense when integrity errors are seen in the system.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800140
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700141### LFSR Initialization Feature
142
143Since the scrambling device uses a block cipher in CTR mode, it is undesirable to initialize the memory with all-zeros from a security perspective, as that would reveal the XOR keystream.
144To this end, the `sram_ctrl` contains an LFSR-based initialization mechanism that overwrites the the entire memory with pseudorandom data.
145
Hugo McNally6321c5e2023-02-16 21:39:55 +0000146Initialization can be triggered via the [`CTRL.INIT`](data/sram_ctrl.hjson#ctrl) CSR, and once triggered, the LFSR is first re-seeded with the nonce that has been fetched together with the scrambling key.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700147Then, the memory is initialized with pseudorandom data pulled from the LFSR.
148For each pseudorandom 32bit word, the initialization mechanism computes the corresponding integrity bits and writes both the data and integrity bits (39bit total) through the scrambling device using the most recently obtained scrambling key.
149
Michael Schaffnere19d8722022-01-21 22:14:01 -0800150If SW triggers the scrambling key update and LFSR initialization at the same time (i.e., with the same CSR write operation), the LFSR initialization will be stalled until an updated scrambling key has been obtained.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700151
152There is no limit on how often the initialization feature can be called, and hence it can also be used as a cheap SRAM wiping mechanism at runtime.
153Note however that the PRNG sequence does not have strong security guarantees, since it is produced using an LFSR.
154
155### Code Execution from SRAM
156
157The SRAM controller contains an access control mechanism for filtering instruction fetches from the processor.
Hugo McNally6321c5e2023-02-16 21:39:55 +0000158As illustrated below, an OTP switch EN_SRAM_IFETCH (see [OTP memory map](../otp_ctrl/README.md#direct-access-memory-map)) allows to either tie code execution from SRAM to the life cycle state via the HW_DEBUG_EN function (see [life cycle docs](../lc_ctrl/README.md#hw_debug_en)), or it can be enabled / disabled via the [`EXEC`](data/sram_ctrl.hjson#exec) CSR.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700159
Hugo McNallyaef0a662023-02-11 19:44:55 +0000160![SRAM Code Execution](./doc/sram_ctrl_sram_execution.svg)
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700161
162The different configuration options are listed in the table below:
163
164
Silvestrs Timofejevsac4e5d52021-10-29 12:56:22 +0100165 EN_SRAM_IFETCH (OTP) | HW_DEBUG_EN (Life Cycle) | EXEC CSR | Execution Enabled
166------------------------|--------------------------|------------------------|--------------------
167 == kMultiBitBool8True | - | == kMultiBitBool4True | Yes
168 == kMultiBitBool8True | - | != kMultiBitBool4True | No
169 != kMultiBitBool8True | ON | - | Yes
170 != kMultiBitBool8True | OFF | - | No
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700171
Michael Schaffnercc4621a2021-10-29 12:09:10 -0700172Note that the execute from SRAM feature may only be enabled on certain SRAM controller instances in the top-level design.
Michael Schaffner1d09fe62022-01-10 08:57:46 -0800173If the feature is turned off via the `InstrExec` parameter, the execute from SRAM feature is permanently disabled, and the status of the OTP switch, the life cycle state and the value of the EXEC register are irrelevant.
Michael Schaffnercc4621a2021-10-29 12:09:10 -0700174
175As an example, the `top_earlgrey` design only enables this feature on the main SRAM, and permanently disables it on the retention SRAM.
176
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800177### Read and Write Sequencing
178
179For timing reasons, the scrambling primitive instantiates a register halfway in the PRINCE block cipher.
180This means that the keystream block becomes available in the second request cycle, which naturally aligns with read operations since the SRAM memory latency is 1 clock cycle.
181
182However, write operations have to be deferred by 1 cycle in order to be able to reuse the same PRINCE primitive.
183This can lead to read/write conflicts when a write operation is immediately followed by a read operation, and we solve that issue by introducing two write data holding registers (highlighted with green and orange in the block diagram above).
184The register highlighted with green is the unscrambled data holding register, which is used for forwarding unwritten write data in case the conflicting read operation goes to the same address as the pending write operation.
185The register highlighted with orange is the scrambled data holding register, which holds the scrambled data until the conflicting read operation(s) have completed.
186
187Note that this arrangement still allows full read/write throughput as illustrated in the alternating R/W sequence below.
188
Hugo McNallyaef0a662023-02-11 19:44:55 +0000189![SRAM Controller Sequencing](./doc/sram_ctrl_sequencing.svg)
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800190
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700191However, due to the end-to-end bus integrity scheme, sub-word write accesses currently require a read-modify-write operation in order to recompute the integrity bits for the entire word, as illustrated in the diagram below.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800192
Hugo McNallyaef0a662023-02-11 19:44:55 +0000193![SRAM Controller Sub-word Write](./doc/sram_ctrl_sub_word_write.svg)
Michael Schaffnera3bedf52020-12-03 20:22:10 -0800194
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700195Sub-word write accesses are therefore 3x slower than full-word write accesses.
196Read accesses however always take 1 cycle, no matter whether the access is a full-word or sub-word read operation.
Michael Schaffnera3bedf52020-12-03 20:22:10 -0800197
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700198Note that this has been implemented in this way to not overly complicate the design, and since it is assumed that sub-word write operations happen relatively infrequently.
199For full write throughput, a more elaborate write buffering scheme would be required.
Michael Schaffner86c0e322020-10-07 19:56:32 -0700200
201# Programmer's Guide
202
203## Initialization
204
205The memory inside the SRAM controller can be used right away after a system reset.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800206However, since the scrambling key defaults to a predefined value, it is recommended that SW performs the following initialization steps as early in the boot process as possible.
Michael Schaffner86c0e322020-10-07 19:56:32 -0700207
Hugo McNally6321c5e2023-02-16 21:39:55 +00002081. Request an updated ephemeral scrambling key from OTP by writing 0x1 to [`CTRL.RENEW_SCR_KEY`](data/sram_ctrl.hjson#ctrl).
209 SW should spin on [`STATUS.SCR_KEY_VALID`](data/sram_ctrl.hjson#status) to wait until the new key has been obtained.
Michael Schaffner35ef7fe2022-07-15 10:03:22 -0700210 While this is not strictly needed since memory accesses to the SRAM will be stalled until the updated key has been obtained, the PC value upon a watchdog crash will be more informative when using a spin wait.
Michael Schaffner86c0e322020-10-07 19:56:32 -0700211
Hugo McNally6321c5e2023-02-16 21:39:55 +00002122. (optional) Initialize the memory with pseudo random data by writing 0x1 to [`CTRL.INIT`](data/sram_ctrl.hjson#ctrl)
213 SW should spin on [`STATUS.INIT_DONE`](data/sram_ctrl.hjson#status) to wait until the memory has been initialized.
Michael Schaffner35ef7fe2022-07-15 10:03:22 -0700214 While this is not strictly needed since memory accesses to the SRAM will be stalled until the initialization is done, the PC value upon a watchdog crash will be more informative when using a spin wait.
Michael Schaffnerc89d9d92021-07-27 18:24:33 -0700215
Hugo McNally6321c5e2023-02-16 21:39:55 +00002163. (optional) Check the [`STATUS.SCR_KEY_SEED_VALID`](data/sram_ctrl.hjson#status) bit:
Michael Schaffner86c0e322020-10-07 19:56:32 -0700217 - In case the scrambling key seeds have been fully provisioned to OTP, this bit should be set to 0x1. A value of 0x0 indicates that the OTP could be malfunctioning or has been tampered with.
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800218 - If the scrambling seeds have not yet been provisioned to OTP, this bit is set to 0x0. The scrambling key will in that case still be ephemeral, but the key seed mixed in as part of the key derivation process will be set to a predefined netlist constant.
Michael Schaffner86c0e322020-10-07 19:56:32 -0700219
Hugo McNally6321c5e2023-02-16 21:39:55 +00002204. (optional) Lock down write access to [`CTRL`](data/sram_ctrl.hjson#ctrl) by writing to [`CTRL_REGWEN`](data/sram_ctrl.hjson#ctrl_regwen) if future key renewals and initializations should be disallowed until the next system reset.
Michael Schaffner86c0e322020-10-07 19:56:32 -0700221
Michael Schaffnere19d8722022-01-21 22:14:01 -0800222Note that before (re-)requesting an updated SRAM key it is imperative to make sure that:
Michael Schaffner86c0e322020-10-07 19:56:32 -0700223- The memory contents are not needed anymore. Requesting a key implicitly wipes all data in the SRAM.
224- The CSRNG and the entropy distribution network have been initialized. The key derivation mechanism in OTP needs to request a chunk of fresh entropy, and that request will block until the entropy distribution network responds.
225
Michael Schaffner9a1bfee2020-12-21 19:21:25 -0800226It should also be noted that data and address scrambling is never entirely disabled - even when the default scrambling key is used.
Michael Schaffner86c0e322020-10-07 19:56:32 -0700227
Timothy Trippelf82e75a2022-07-27 14:42:22 -0700228## Device Interface Functions (DIFs)
229
Hugo McNallyac9f9b52023-02-14 12:15:34 +0000230- [Device Interface Functions](../../../sw/device/lib/dif/dif_sram_ctrl.h)
Timothy Trippelf82e75a2022-07-27 14:42:22 -0700231
Michael Schaffner86c0e322020-10-07 19:56:32 -0700232## Register Table
233
Hugo McNallyba16bae2023-02-12 21:08:04 +0000234* [Register Table](data/sram_ctrl.hjson#registers)