Skip to content

Commit

Permalink
[hmac,doc] Update Save and Restore SW guide
Browse files Browse the repository at this point in the history
- After this issue lowRISC#24767 has been raised, and a workaround has been
found lowRISC#24944, the Programmer's Guide should be updated to reflect this.

Signed-off-by: Martin Velay <[email protected]>
  • Loading branch information
martin-velay committed Oct 31, 2024
1 parent 05db155 commit e6da4e3
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions hw/ip/hmac/doc/programmers_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,21 @@ When SW doesn't know each instant at which a full message block is available, it

The context that needs to be saved and restored is in the following registers: [`CFG`](registers.md#cfg), [`DIGEST_*`](registers.md#digest), and [`MSG_LENGTH_*`](registers.md#msg_length_lower).

**An RTL bug has been found where the HW is unable to recover if a stop command is issued after the HASH has been processed, more details [here](https://github.com/lowRISC/opentitan/issues/24767). A SW [workaround has been found](https://github.com/lowRISC/opentitan/pull/24944) and implies to adapt the way to use this feature. The temporary changes are marked in italics and replace the previous "normal" operations, which are striked through.**

Each new message stream needs to be started *once* by setting the `CMD.hash_start` bit and finalized *once* by setting the `CMD.hash_process` bit.
To switch from one message stream to another, set the `CMD.hash_stop` bit, wait for the `hmac_done` interrupt (or status bit), save one context and restore the other, and then set the `CMD.hash_continue` bit.
To switch from one message stream to another, ~~set the `CMD.hash_stop` bit, wait for the `hmac_done` interrupt (or status bit)~~ _at a block boundary, insert delay which should be equivalent to at least 80 clock cycles_, save one context, _trigger `CMD.hash_process` to move the FSMs into a stable state_ and restore the other context, and then set the `CMD.hash_continue` bit.

Here is an example usage pattern of this feature:
1. Start processing message stream A by configuring HMAC and then setting the `CMD.hash_start` bit.
1. Write an arbitrary number of message blocks to HMAC's `MSG_FIFO`.
1. Stop HMAC by setting the `CMD.hash_stop` bit and wait for the `hmac_done` interrupt (or poll the interrupt status register).
1. _Insert a delay of least 80 clock cycles._
~~1. Stop HMAC by setting the `CMD.hash_stop` bit and wait for the `hmac_done` interrupt (or poll the interrupt status register).~~
1. Save the context by reading the `DIGEST_0`..`15` and `MSG_LENGTH_`{`LOWER`,`UPPER`} registers.
If the operation is keyed HMAC, the values of `KEY_0`..`X` registers also need to be maintained as part of the context, where `X` is the last register used for the given key length (e.g. for HMAC-256, `X=7`).
However, key registers cannot be read from SW, therefore SW must maintain key values as part of its own context during initialization.
Similarly, the value of the `CFG` register must also be preserved, and SW should keep its value separately, instead of reading it from `CFG` register.
1. _Trigger `CMD.hash_process`_
1. Disable `sha_en` by updating `CFG` register, in order to clear the digest from stream A.
This is necessary to also prevent leakage of intermediate context of one SW thread to another.
1. Repeat steps 1-5 for message stream B.
Expand Down

0 comments on commit e6da4e3

Please sign in to comment.