lowRISC / lowRISC/opentitan

[otbn,rtl] Glitch in the STATUS register on way to LOCKED after an RMA

Open
#23,903 1 comment 0 reactions 0 assignees View on GitHub
Component:RTL IP:otbn Type:FutureRelease
Dominant language
SystemVerilog
Stars
3.6k
Forks
1.1k
Avg merge
2d 22h
Merged PRs (30d)
141

Description

### Description

If an RMA request comes in when OTBN is idle, the STATUS register spends a cycle LOCKED (`0xff`), before jumping to secure wipe (`0x04`) for a while before it finally goes back to LOCKED.

It happens as follows:

- When OTBN is idle, `otbn_controller` will be in state `OtbnStateHalt` and `otbn_start_stop_control` will be in state `OtbnStartStopStateHalt`.
- Suppose an RMA request comes in.
- This appears to the controller as as `lc_rma_req_i` and the controller jumps to `OtbnStateLocked`.
- The controller exposes a `locking_o` signal, which essentially controls forces the `STATUS` register to be LOCKED. This is computed as follows:
```systemverilog
assign locking_o = (state_d == OtbnStateLocked) & (~(secure_wipe_running_i | secure_wipe_req_o) |
urnd_reseed_err_i | mubi_err_d);
```
- The idea is that we want `STATUS` to become LOCKED once the secure wipe has finished running.
- Unfortunately, `secure_wipe_running_i` lags behind `state_d` here! It is computed by otbn_start_stop_control, where it is the value of `secure_wipe_running_q`.
- There's a cycle where state_d is `OtbnStateLocked` and `secure_wipe_running_d` is true, but `secure_wipe_running_q` (the registered value) hasn't yet gone high.
- The end result is that `STATUS` is LOCKED for a single cycle and then jumps to the secure wipe state for a while before going back to LOCKED. This contradicts the idea that the LOCKED status is terminal.

This is not a particularly critical bug, as it only exposes itself as a weird transient value in a status register. And I only found it because some of the DV code looks at that register every cycle. But I think it's probably worth fixing in a future version.

Here are some waves showing the problem. The final row is the value of `status_q` in `otbn.sv`, which is exposed directly as the contents of the STATUS register.
![image](https://github.com/lowRISC/opentitan/assets/104845/aa2ac148-9f05-43d4-97ff-bb403434638f)

Contributor guide

Open the contributing guide

Research direction

Read the STATUS path in otbn.sv and the state and signal logic in otbn_controller and otbn_start_stop_control. Reproduce the idle-to-RMA transition described in the issue and inspect the cycle-by-cycle values of state_d, secure_wipe_running_q, and status_q. Done means the transient LOCKED value no longer appears before secure wipe and the terminal status behavior is covered by verification.

Written by the indexing model from the issue text.

Assessment

Domain
embedded-iot, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.