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

[prim_fifo_sync,rtl] Specialize for Depth == 1 #25461

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

rswarbrick
Copy link
Contributor

This case is pretty simple to reason about, and avoids needing proper read and write addresses (because there is only one element).

This has seen some FPV testing (util/dvsim/dvsim.py hw/top_earlgrey/formal/top_earlgrey_fpv_prim_cfgs.hjson --select-cfg=prim_fifo_sync_fpv) and passes happily. This was inspired by #25419 (or, more precisely, I was!) so I thought it made sense to implement.

Closes #25419.

@rswarbrick
Copy link
Contributor Author

Force-push wires up the full_o output (which wasn't tested by the FPV: a fact I only discovered from trying to fix some warnings from Jasper...)

@rswarbrick
Copy link
Contributor Author

Force-push wires up the other output that I'd missed...

Thinking about err_o makes me realise that this might not be hardened enough. We now have 1 bit of storage (full_q) which is not hardened, where it was hardened with the existing implementation. Adding the hardening wouldn't be hard, but I'd be interested to hear from someone who knows more about HW security. @andreaskurth, could you give me some pointers? :-)

Copy link
Contributor

@matutem matutem left a comment

Choose a reason for hiding this comment

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

I left a couple suggestions, otherwise LGTM. Thanks for taking this one :)

@rswarbrick
Copy link
Contributor Author

Thanks for the review, @matutem. I've addressed the comments (I hope) and force-pushed. I think there's still a question about security hardening and I'm hoping someone who knows more about security than me (@andreaskurth? @vogelpi?) would be able to weigh in.

@rswarbrick rswarbrick requested a review from vogelpi December 2, 2024 11:20
Copy link
Contributor

@vogelpi vogelpi left a comment

Choose a reason for hiding this comment

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

I am not sure I understand the motivation of this PR. It doesn't mean I cannot support it but I would first like to understand before spending time on reviewing this. As noted in the discussion, this can have security impact, so a careful review is needed here.

@rswarbrick can you please clarify? My understanding is that with the current design and a depth of 0, we instantiate the prim_fifo_sync_cnt modules even though they are not used - there is a single module storage entry anyway and we always write that one and read from it. The prim_fifo_sync_cnt modules mean some waste of area due to the prim_flops inside and coverage cannot be closed for this as is. Is this correct?

@rswarbrick
Copy link
Contributor Author

Yes, I think that is correct, which is the reason for @matutem's original issue (I think).

Copy link
Contributor

@vogelpi vogelpi left a comment

Choose a reason for hiding this comment

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

The unhardened implementation looks good to me but I think adding a second flop (using prim_flop) in the case Secure is set to 1 would make sense.

Can you please also check if there are any instances in the design with Depth == 1 and Secure == 1? Because for blocks using such instantiations we have very likely some FI tests that will break with this PR. Because the faults are typically injected into either the read or the write pointers which are no longer there with this PR.

@rswarbrick
Copy link
Contributor Author

I've just worked through the tree a bit to search for examples of this. And I've found at least some! The three fifos in tlul_adapter_sram are set to secure if the adapter is instantiated with SecFifoPtr=1. This happens in otbn, rom_ctrl, sram_ctrl and flash_ctrl.

@rswarbrick
Copy link
Contributor Author

I've just pushed up a version with the duplicated 1-bit counter that I think we'd need. Looking closely, I don't think this will actually break any testing. But that's because we do the tests by injecting things into instances of prim_count (which I would be removing).

Clearly, it would cause the testing to miss security holes! So I'm going to poke around now and see whether I can replicate the testing sensibly in this case.

@rswarbrick rswarbrick requested a review from a team as a code owner December 5, 2024 21:35
@rswarbrick rswarbrick requested review from marnovandermaas and removed request for a team December 5, 2024 21:35
@rswarbrick
Copy link
Contributor Author

Well, that was harder than I expected! I've just force pushed with a much larger commit (sorry) that I'm hoping will fix lots of the build failures with the previous version. Frustratingly, I can't really see an easy way to split it up.

@rswarbrick rswarbrick force-pushed the singleton-fifo branch 3 times, most recently from 2fce3e1 to 8fddc7a Compare December 5, 2024 21:59
Copy link
Contributor

@vogelpi vogelpi left a comment

Choose a reason for hiding this comment

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

Thanks @rswarbrick for going the extra miles with the automated countermeasure tests, this helps keeping the nightlies healthy and avoids someone else debugging afterwards.

I think for the entropy complex (EDN, CSRNG, ENTROPY_SRC) we do have non-automated tests injecting errors into all FIFOs, see e.g. csrng_err_vseq.sv. I am not sure but I believe these sequences will now fail as the paths into the depth == 1 FIFOs no longer exists. This is only detected at runtime. Can you please run full regressions for these three blocks to be sure? I think a 10% regression should be sufficient to hit these cases.

hw/ip/prim/rtl/prim_fifo_sync.sv Outdated Show resolved Hide resolved
@vogelpi
Copy link
Contributor

vogelpi commented Dec 6, 2024

Ah and for the new DV interfaces and assertions, I would appreciate if @matutem could take another look please.

This case is pretty simple to reason about, and avoids needing proper
read and write addresses (because there is only one element).

Unfortunately, it's quite a big commit! This is because we end up
changing some of the duplicated counters inside the fifo. Items in the
commit:

 - Update the RTL in prim_fifo_sync.sv to specialize as you'd expect.

 - Add an interface that can be bound in to prim_fifo_sync.sv and will
   register a way for sec_cm tests to use forced signals to simulate
   fault injections.

 - Bind that interface into the prim_fifo_sync instances

 - Wrap up the ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT calls that are
   used for prim_fifo_sync instances. After the change, the two macro
   calls that were previously used (for the read and write pointer)
   are now handled by a single macro.

   In instances with Depth >= 2, this turns into
   ASSERT_PRIM_FIFO_SYNC_ERROR_TRIGGERS_ALERT. For singleton
   instances, it's ASSERT_PRIM_FIFO_SYNC_ERROR_TRIGGERS_ALERT1. I
   don't *think* you can make the dispatch between the two options
   automatic (because the pre-processor can't know the values of the
   Depth parameter).

- Use these new macros in the various blocks that were using
  prim_fifo_sync in secure mode with Depth = 1. This is CSRNG, OTBN
  and flash_ctrl.

Signed-off-by: Rupert Swarbrick <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[rtl,prim_fifo_sync] Avoid counters when Depth == 1
3 participants