Skip to content

[otbn] RTL implementation of the KMAC interface#30283

Merged
nasahlpa merged 1 commit into
lowRISC:masterfrom
etterli:otbn-rtl-kmac-if
Jun 16, 2026
Merged

[otbn] RTL implementation of the KMAC interface#30283
nasahlpa merged 1 commit into
lowRISC:masterfrom
etterli:otbn-rtl-kmac-if

Conversation

@etterli

@etterli etterli commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

The last commit of this PR implements the OTBN side of the KMAC interface. The interface is specified in #30278.

All other commits are part of one of these PRs:

@etterli etterli changed the title Otbn rtl kmac if [otbn] RTL implementation of the KMAC interface Jun 3, 2026
@etterli etterli force-pushed the otbn-rtl-kmac-if branch 2 times, most recently from 44b855f to 4ab11e9 Compare June 4, 2026 11:18
@etterli

etterli commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

The interface no longer automatically sends a process command when a partial message is sent. It just detects it and waits for SW to issue a process command.

@etterli etterli force-pushed the otbn-rtl-kmac-if branch 2 times, most recently from 039bb39 to a0cf520 Compare June 4, 2026 11:41
Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv Outdated
Comment on lines +805 to +807
////////////////////////////////////
// KMAC_DATA_Sx secure wipe delay //
////////////////////////////////////

@etterli etterli Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This whole concept of delaying the secure wipe for the relevant 64 bits (or rather 128 for both shares) of the message is quite ugly. But I haven't found a better way how to ensure that the data does not change. And there is an assertion in the msg FIFO inside the KMAC (prim packer and also downstream) that it must remain stable.

Any idea is welcome.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In my view we don't need to buffer / delay the secure wipe word here for the following reasons:

  • The secure wipe is fed from URND and we do two wipes with a URND reseed in between.
  • We do two wipes with a reseed in between to not allow recovering the URND output of the first wipe as this could potentially allow for a SCA attack on the secret using the leakage between the secret and the URND output.
  • The secret here is always shared because KMAC consumes and provides shared data. So there would be at most second order leakage. This is different from regular WDRs where we can have shared and unshared data.

So instead of buffering / delaying the wipe I would do the following:

  • If there is not outstanding request, wipe based on the wipe input signal and using URND.
  • If there is an outstanding request
    • Track that we have to do the wipe at a later point.
    • Once that point comes, generate a URND update/advance signal (no reseed). At that point, the main wipe may have finished and OTBN may be idle (URND at rest) otherwise.
  • Wipe the entire WSRs instead of individual 64-bit beats to reduce complexity.

Would that work?

Alternatively, I would also be fine to not adhere to the valid-locked-in principle here. This is really a corner case and I am not sure we will be able to trigger this at the top level. We may be able to trigger it with a FI simulation test but then can also deactivate the relevant SVAs in KMAC and reason why this is necessary for that specfiic test.

@etterli etterli Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the proposal. This sounds good. Not guaranteeing two wipes for these WSRs just means that these should not be used as extra WDRs when the KMAC IF is not used.

I also checked the consequences of not adhering to the valid locked-in principle again in more detail. If it is violated, then the only consequence is that the digest value computed by the KMAC is undefined. But it does not lock up the KMAC IP. The recovery mechanism will still bring the KMAC IP back to the Idle state. And when a secure wipe happens, we anyway ignore any digest data. The strobe however should be stable.

Therefore, I think the best is if we just secure wipe these registers in the normal way and accept the corner case. The configuration and strobe registers can simply be reset to the default values once the recovery ends.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fully agree, thanks @etterli !

Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
@etterli etterli force-pushed the otbn-rtl-kmac-if branch 8 times, most recently from 8d318c7 to b116425 Compare June 5, 2026 15:08
Comment on lines +720 to +721
// Extract command from write.
assign current_cmd = ispr_kmac_ctrl_w.cmd & {$bits(kmac_cmd_t){ispr_kmac_ctrl_wr_i}};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This extracts the cmd from the current instruction and thus makes current_cmd combinatorial. I designed the FSM in such a way that there is no timing path directly to the interface. But maybe it would make more sense if the write goes to an actual register and the FSM decides on a flopped value?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hm, good question. If we used a CSRWI instruction, the command would come out of an immediate but also other paths would be possible. Maybe we need a 1 cycle delay then for the START command. This shouldn't be critical for performance as it's done just once per session.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We now have already a one cycle delay because the FSM will issue the request in another state than when it detects the command (OtbnKmacIdle vs OtbnKmacStarting, and similar for all other commands). In OtbnKmacIdle the state transition depends on the command. And in OtbnKmacStarting the FSM sets the request valid signal but the command signal is not evaluated anymore.

The question now is whether having 2 states actually serves as a cut between the command signal and the request signal generation. This comes down how the FSM is implemented/optimized when synthesizing the design. But I suggest let's do a synthesis and see the effect. This would be easy to refactor.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, I fully agree with you here.

@etterli etterli force-pushed the otbn-rtl-kmac-if branch from b116425 to 4cb285f Compare June 8, 2026 14:50
@rswarbrick rswarbrick removed their request for review June 9, 2026 09:32

@vogelpi vogelpi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Pascal, this looks pretty nice so far. I've reviewed the first half and will continue later.

Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv Outdated

@etterli etterli left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @vogelpi for the first review. Here is the updated version. The KMAC_CTRL is now split into KMAC_CTRL and KMAC_CFG.

Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
@etterli etterli force-pushed the otbn-rtl-kmac-if branch from 4cb285f to f439c5c Compare June 9, 2026 19:56

@vogelpi vogelpi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've now also reviewed the rest. I would try to simplify the secure wipe (it's a corner case) and instead optimize the digest reading (the fast case we care about).

Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment on lines +728 to +729
// TODO: Do we need integrity or any other duplication? We could duplicate the config and then
// send the config on both data share signals.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, I would just do that. And I would duplicate these bits also in the CSR. So software would have to provide the config for both shares. These couple of flops are not expensive but it's a lot simpler from a hardening perspective than reasoning about where what could go wrong.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ok if we postpone this because it also requires changes on the KMAC side? I created an issue for this. Rephrased the TODO so it's no longer a question.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, it doesn't require KMAC side changes. KMAC should ignore share1 for config commands, no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah yes true. It is now implemented on the OTBN side.

Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment on lines +747 to +748
// TODO: Do we need integrity?
assign ispr_kmac_strb_rdata_o = kmac_strb_q;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it should be sufficient to check on the receiving side, i.e., inside KMAC that there are no empty message beats (strobe == 0) in between the last beat and the process command. I am not worried about dropping or shortening a single beat, but more about sending all-zero messages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Manipulating the strobe can result in undefined behaviour / digest values or a message is interpreted as empty message. Both cases must be detected somehow. I agree that this should be handled on the KMAC side because otherwise we would also have to harden the data signals.

Created an issue for this.

Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv Outdated
Comment thread hw/ip/otbn/rtl/otbn_kmac_if.sv Outdated
Comment on lines +805 to +807
////////////////////////////////////
// KMAC_DATA_Sx secure wipe delay //
////////////////////////////////////

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In my view we don't need to buffer / delay the secure wipe word here for the following reasons:

  • The secure wipe is fed from URND and we do two wipes with a URND reseed in between.
  • We do two wipes with a reseed in between to not allow recovering the URND output of the first wipe as this could potentially allow for a SCA attack on the secret using the leakage between the secret and the URND output.
  • The secret here is always shared because KMAC consumes and provides shared data. So there would be at most second order leakage. This is different from regular WDRs where we can have shared and unshared data.

So instead of buffering / delaying the wipe I would do the following:

  • If there is not outstanding request, wipe based on the wipe input signal and using URND.
  • If there is an outstanding request
    • Track that we have to do the wipe at a later point.
    • Once that point comes, generate a URND update/advance signal (no reseed). At that point, the main wipe may have finished and OTBN may be idle (URND at rest) otherwise.
  • Wipe the entire WSRs instead of individual 64-bit beats to reduce complexity.

Would that work?

Alternatively, I would also be fine to not adhere to the valid-locked-in principle here. This is really a corner case and I am not sure we will be able to trigger this at the top level. We may be able to trigger it with a FI simulation test but then can also deactivate the relevant SVAs in KMAC and reason why this is necessary for that specfiic test.

@etterli etterli force-pushed the otbn-rtl-kmac-if branch from f439c5c to bded919 Compare June 10, 2026 16:02
@etterli

etterli commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

The latest version features:

  • Rebased on the newest version of [kmac] Extend KMAC app interface with a dynamic interface type #30143 (minimized DV changes and squashed everything).
  • The implementation of the new OTBN SW command CLOSE
  • Simplified the secure wipe behaviour for KMAC_DATA_S0/1.
    • These are now wipe like any other WSR.
    • We accept the corner case that we violate the valid locked-in principle for the request channel when a wipe happens whilst sending a message.
  • The interface is now capable of accepting the next response in the same cycle the previous digest is consumed/read.

@etterli etterli force-pushed the otbn-rtl-kmac-if branch 5 times, most recently from 2b8e25d to cd9a0b5 Compare June 11, 2026 12:32

@vogelpi vogelpi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Very nice, thanks for the various improvements @etterli !

@nasahlpa nasahlpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks Pascal - I have checked whether the RTL matches the spec, which is the case.

@etterli etterli force-pushed the otbn-rtl-kmac-if branch from cd9a0b5 to b048304 Compare June 12, 2026 14:07

@etterli etterli left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have now addressed all the feedback and implemented the duplicated KMAC_CFG register.

Also see #30384 for how the interface is integrated into OTBN.

Comment on lines +720 to +721
// Extract command from write.
assign current_cmd = ispr_kmac_ctrl_w.cmd & {$bits(kmac_cmd_t){ispr_kmac_ctrl_wr_i}};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We now have already a one cycle delay because the FSM will issue the request in another state than when it detects the command (OtbnKmacIdle vs OtbnKmacStarting, and similar for all other commands). In OtbnKmacIdle the state transition depends on the command. And in OtbnKmacStarting the FSM sets the request valid signal but the command signal is not evaluated anymore.

The question now is whether having 2 states actually serves as a cut between the command signal and the request signal generation. This comes down how the FSM is implemented/optimized when synthesizing the design. But I suggest let's do a synthesis and see the effect. This would be easy to refactor.

Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
Comment on lines +728 to +729
// TODO: Do we need integrity or any other duplication? We could duplicate the config and then
// send the config on both data share signals.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah yes true. It is now implemented on the OTBN side.

Comment thread hw/ip/otbn/rtl/otbn_kmac.sv Outdated
@etterli etterli force-pushed the otbn-rtl-kmac-if branch 2 times, most recently from 10b4d80 to 8b5d864 Compare June 15, 2026 09:36
@etterli etterli requested a review from vogelpi June 15, 2026 09:58
Signed-off-by: Pascal Etterli <pascal.etterli@lowrisc.org>
@etterli etterli force-pushed the otbn-rtl-kmac-if branch from 8b5d864 to 5299174 Compare June 15, 2026 13:58
@etterli etterli marked this pull request as ready for review June 15, 2026 13:59

@vogelpi vogelpi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, this looks really great @etterli !

Comment on lines +720 to +721
// Extract command from write.
assign current_cmd = ispr_kmac_ctrl_w.cmd & {$bits(kmac_cmd_t){ispr_kmac_ctrl_wr_i}};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, I fully agree with you here.

@vogelpi

vogelpi commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

CHANGE AUTHORIZED: hw/ip/otbn/rtl/otbn_kmac_if.sv

@vogelpi vogelpi added the CI:Rerun Rerun failed CI jobs label Jun 16, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Jun 16, 2026
@nasahlpa

Copy link
Copy Markdown
Contributor

CHANGE AUTHORIZED: hw/ip/otbn/rtl/otbn_kmac_if.sv

@nasahlpa

Copy link
Copy Markdown
Contributor

merging as the Private CI run already passed but it is not correctly visualized here and the time out in the FPGA test run is fine.

@nasahlpa nasahlpa added this pull request to the merge queue Jun 16, 2026
Merged via the queue into lowRISC:master with commit 0c4e476 Jun 16, 2026
43 of 47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants