[otbn] RTL implementation of the KMAC interface#30283
Conversation
44b855f to
4ab11e9
Compare
|
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. |
039bb39 to
a0cf520
Compare
| //////////////////////////////////// | ||
| // KMAC_DATA_Sx secure wipe delay // | ||
| //////////////////////////////////// |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
8d318c7 to
b116425
Compare
| // Extract command from write. | ||
| assign current_cmd = ispr_kmac_ctrl_w.cmd & {$bits(kmac_cmd_t){ispr_kmac_ctrl_wr_i}}; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Yes, I fully agree with you here.
vogelpi
left a comment
There was a problem hiding this comment.
Thanks Pascal, this looks pretty nice so far. I've reviewed the first half and will continue later.
vogelpi
left a comment
There was a problem hiding this comment.
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).
| // TODO: Do we need integrity or any other duplication? We could duplicate the config and then | ||
| // send the config on both data share signals. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Actually, it doesn't require KMAC side changes. KMAC should ignore share1 for config commands, no?
There was a problem hiding this comment.
Ah yes true. It is now implemented on the OTBN side.
| // TODO: Do we need integrity? | ||
| assign ispr_kmac_strb_rdata_o = kmac_strb_q; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| //////////////////////////////////// | ||
| // KMAC_DATA_Sx secure wipe delay // | ||
| //////////////////////////////////// |
There was a problem hiding this comment.
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.
f439c5c to
bded919
Compare
|
The latest version features:
|
2b8e25d to
cd9a0b5
Compare
nasahlpa
left a comment
There was a problem hiding this comment.
Thanks Pascal - I have checked whether the RTL matches the spec, which is the case.
cd9a0b5 to
b048304
Compare
| // Extract command from write. | ||
| assign current_cmd = ispr_kmac_ctrl_w.cmd & {$bits(kmac_cmd_t){ispr_kmac_ctrl_wr_i}}; |
There was a problem hiding this comment.
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.
| // TODO: Do we need integrity or any other duplication? We could duplicate the config and then | ||
| // send the config on both data share signals. |
There was a problem hiding this comment.
Ah yes true. It is now implemented on the OTBN side.
10b4d80 to
8b5d864
Compare
Signed-off-by: Pascal Etterli <pascal.etterli@lowrisc.org>
8b5d864 to
5299174
Compare
| // Extract command from write. | ||
| assign current_cmd = ispr_kmac_ctrl_w.cmd & {$bits(kmac_cmd_t){ispr_kmac_ctrl_wr_i}}; |
There was a problem hiding this comment.
Yes, I fully agree with you here.
|
CHANGE AUTHORIZED: hw/ip/otbn/rtl/otbn_kmac_if.sv |
|
CHANGE AUTHORIZED: hw/ip/otbn/rtl/otbn_kmac_if.sv |
|
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. |
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: