Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hmac] Initial implementation of save & restore #21307

Merged
merged 26 commits into from
Feb 27, 2024

Conversation

andreaskurth
Copy link
Contributor

@andreaskurth andreaskurth commented Feb 12, 2024

This is an initial implementation of save & restore for HMAC (issue #49), which should allow SW to switch between different parallel message streams. In short, SW usage follows a pattern like this:

  1. Start processing message stream A by configuring HMAC and then setting the CMD.hash_start bit.
  2. Write an arbitrary number of message blocks to HMAC's MSG_FIFO.
  3. Stop HMAC by setting the CMD.hash_stop bit and wait for the hmac_done interrupt (or poll the interrupt status register).
  4. Save the context by reading the DIGEST_0..7 and MSG_LENGTH_{LOWER,UPPER} registers. (The values in the CFG register must also be preserved, but that is purely SW-controlled so doesn't need to be read from HW.)
  5. Repeat steps 1-4 for message stream B.
  6. Restore the context of message stream A by writing the CFG, DIGEST_0..7, and MSG_LENGTH_{LOWER,UPPER} registers.
  7. Continue processing message stream A by setting the CMD.hash_continue bit.
  8. Write an arbitrary number of message blocks to HMAC's MSG_FIFO.
  9. Continue this with as many message blocks and parallel message streams as needed. The final hash for any message stream can be obtained at any time (no need for complete blocks) as before by setting CMD.hash_process and waiting for the hmac_done interrupt / status bit, finally reading the digest from the DIGEST registers.

A noteworthy limitation of this implementation is that context can only be switched on complete message blocks (512 bit for SHA-256). This is so that no additional internal state (i.e., working variables and round counter) needs to be exposed to and controlled from SW. As noted in issue #49, this shouldn't be a major limitation for SW, though.

Although this PR adds preliminary DV support for the changes, save & restore does not yet get checked by the tests (the save_and_restore_pct randomization knob is currently 0 for all tests). I have manually verified that save & restore works under the basic operating conditions for HMAC and SHA but this needs to be tested much more thoroughly, especially the corner cases. When one enables save & restores in the tests, one will get errors from DV. My first assessment is that these are DV limitations, not RTL bugs, though.

I ran a full regression on HMAC to check that this doesn't break existing functionality or DV, and I got the same pass rates as reported in nightlies -- so no breakage of existing RTL & DV expected.

Opens before this PR can be merged:

  • Update documentation (mainly Programmer's Guide and Theory of Operation).

Opens that can be resolved in a follow-up PR:

  • Extend testplan and coverplan to test and cover save & restore feature.
  • Enable save & restores in tests and make necessary extensions to the scoreboard as well as burst_wr_msg so this gets correctly checked and fully covered.
  • Add additional directed test that covers context switching between multiple message streams (not sure if this has to be an UVM test, maybe a SW test would suffice?).

--> tracked in #21708

@andreaskurth andreaskurth added Component:DV DV issue: testbench, test case, etc. Component:RTL IP:hmac labels Feb 12, 2024
@andreaskurth andreaskurth requested a review from a team as a code owner February 12, 2024 15:14
@andreaskurth andreaskurth requested review from hcallahan-lowrisc, rswarbrick, gdessouky, vogelpi and msfschaffner and removed request for a team February 12, 2024 15:14
@andreaskurth
Copy link
Contributor Author

@gdessouky As discussed, here's a first implementation of save & restore. I would be super happy to get your feedback on this. Unless you think this is fundamentally broken, I think it would be good to get this merged soon, so that SW folks can write a small test that exercises this to check that it meets their needs.

@andreaskurth andreaskurth force-pushed the hmac-save-and-restore branch 2 times, most recently from a130858 to dd8b50f Compare February 13, 2024 09:47
@andreaskurth
Copy link
Contributor Author

kokoro reported lint errors that I've fixed by now; the remaining flow errors seem to be spurious.

Copy link
Contributor

@rswarbrick rswarbrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nitty comments about the first few commits. I've got as far as "Make MSG_LENGTH CSRs SW-writable". There are a few commits to go yet...

Copy link
Contributor

@rswarbrick rswarbrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of nitty comments, but this looks sensible in general.

In future, I'd definitely suggest splitting up giant PRs into chains that depend on one another. It becomes a bit easier to review and you can "merge the first chunk" rather quicker :-)

@@ -195,6 +201,24 @@
based on currently received message.
'''
}
{ bits: "2",
name: "hash_stop",
Copy link
Contributor

@msfschaffner msfschaffner Feb 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moidx @jadephilipoom @ballifatih can you take a look at the API changes to double check this is fulfills the requirements of the cryptolib?

6. Restore the context of message stream A by writing the `CFG`, `DIGEST_0`..`7`, and `MSG_LENGTH_`{`LOWER`,`UPPER`} registers.
7. Continue processing message stream A by setting the `CMD.hash_restart` bit.
8. Write an arbitrary number of message blocks to HMAC's `MSG_FIFO`.
9. Continue this with as many message blocks and parallel message streams as needed. The final hash for any message stream can be obtained at any time (no need for complete blocks) by setting `CMD.hash_process` and waiting for the `hmac_done` interrupt / status bit, finally reading the digest from the `DIGEST` registers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@msfschaffner
Copy link
Contributor

Thanks for doing this (and splitting up the work into multiple easy-to-review commits)!
Overall this looks good to me, but it'd be great to get an ACK from some of the cryptolib devs to make sure this interface fulfills their requirements.

Copy link
Contributor

@jadephilipoom jadephilipoom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! I can confirm that the need to only stop at full message blocks shouldn't be an issue for SW (we can just buffer the trailing partial message block and store it along with the hash state until we're ready to resume).

@gdessouky
Copy link
Contributor

Thanks @andreaskurth, this looks good to me too, but I still hope to go through this in detail later today. Sorry to not have gotten to it yet, but been struggling with DV issues for the extended digest feature at my end :(

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
The components of the `event_intr` signal can directly be fed into the
`prim_intr_hw` modules, so there's no need for this intermediary signal.

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
This signals whether the hash computation is actively running -- as
opposed to `idle_o`, which also is also false (thus 'busy') when waiting
for a FIFO input.

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Prior to this commit, *done* would only be signaled when done with
processing a full message.

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
The chances for doing this save & restore are controlled by the knob
introduced in the previous commit.

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
Signed-off-by: Andreas Kurth <adk@lowrisc.org>
andreaskurth added a commit to andreaskurth/opentitan that referenced this pull request Feb 27, 2024
With the addition of *save & restore* (PR lowRISC#21307) and *wider digest and
configurable key length* (PR lowRISC#21604), HMAC will see major changes.  For
this reason, this commit gives HMAC a major version bump to 2.0.0 and
resets its development stages to L1 (Development), D1 (Functional), V0
(*Initial Work* because the DV environment may not be completely
functional for some time), and S0 (*Initial Work* because the DIF may
not be completely functional for some time).

The previous version 1.0.0 got assigned a commit ID for future reference
even though it had not reached L2, V3, and S3.

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
andreaskurth added a commit that referenced this pull request Feb 27, 2024
With the addition of *save & restore* (PR #21307) and *wider digest and
configurable key length* (PR #21604), HMAC will see major changes.  For
this reason, this commit gives HMAC a major version bump to 2.0.0 and
resets its development stages to L1 (Development), D1 (Functional), V0
(*Initial Work* because the DV environment may not be completely
functional for some time), and S0 (*Initial Work* because the DIF may
not be completely functional for some time).

The previous version 1.0.0 got assigned a commit ID for future reference
even though it had not reached L2, V3, and S3.

Signed-off-by: Andreas Kurth <adk@lowrisc.org>
@andreaskurth andreaskurth merged commit 0ebe13d into lowRISC:master Feb 27, 2024
33 checks passed
@andreaskurth andreaskurth deleted the hmac-save-and-restore branch February 27, 2024 10:19
@msfschaffner
Copy link
Contributor

Awesome, thanks for getting this merged!

This was referenced Mar 28, 2024
Copy link

@cdgori cdgori left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching up to SHA2/HMAC changes in reverse chronological order. This LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component:DV DV issue: testbench, test case, etc. Component:RTL IP:hmac
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants