Skip to content

[hw] Integrate KMAC for ROM checking#590

Merged
elliotb-lowrisc merged 3 commits into
lowRISC:mainfrom
elliotb-lowrisc:kmac
Jun 5, 2026
Merged

[hw] Integrate KMAC for ROM checking#590
elliotb-lowrisc merged 3 commits into
lowRISC:mainfrom
elliotb-lowrisc:kmac

Conversation

@elliotb-lowrisc
Copy link
Copy Markdown
Contributor

@elliotb-lowrisc elliotb-lowrisc commented May 29, 2026

Add KMAC to Mocha and use it to enable ROM scrambling.

See individual commits for details.

Copy link
Copy Markdown
Collaborator

@engdoreis engdoreis left a comment

Choose a reason for hiding this comment

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

The Software bits all looks good to me.

Copy link
Copy Markdown
Collaborator

@marnovandermaas marnovandermaas left a comment

Choose a reason for hiding this comment

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

Great work! Some initial comments from my end.

Comment thread hw/vendor/lowrisc_ip.vendor.hjson Outdated
Comment on lines +34 to +36
{from: "hw/ip/edn", to: "ip/edn"}, // EDN (KMAC dependency).
{from: "hw/ip/keymgr", to: "ip/keymgr"}, // Key Manager (KMAC dependency).
{from: "hw/ip/csrng", to: "ip/csrng"}, // CSRNG (KMAC dependency).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there any way that we can avoid pulling these IP blocks in. Maybe we can just patch out the need for key manager, EDN and CSRNG?

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.

A quick search for package names in the vendored KMAC files show that these would need to be patched: kmac.sv (5 lines), kmac_entropy.sv (5 lines), kmac_app.sv (3 lines).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would you mind attempting this patch so we avoid pulling in these extra three dependencies?

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.

Achieved by patching the few bits required into kmac_pkg.sv

Comment thread hw/top_chip/dv/top_chip_sim_cfg.hjson
localparam int unsigned SPIHostIrqs = 2;
localparam int unsigned EntropySrcIrqs = 4;
localparam int unsigned KmacNumAppIntf = 1;
localparam int unsigned KmacNumAppIntf = 3; // system only needs 1 (rom_ctrl), but KMAC expects 3
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How baked in is this assumption? How many lines would need to change to just have 1?

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.

From what I remember, there was at least one primitive that would either need to be patched itself to fix or be patched out of KMAC, so not trivial. I haven't fully explored how many other things may need to be changed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ok, then this may just not be worth the hassle. It can be an improvement we do later if we need to save area. Maybe we can open an issue to track this?

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.

Done: #599

Comment thread hw/top_chip/rtl/top_chip_system.sv
Comment thread sw/device/bootrom/CMakeLists.txt Outdated
Comment on lines 24 to 25
COMMAND srec_cat "$<TARGET_FILE:${NAME}>.bin" -binary -byte-swap 4
-o "$<TARGET_FILE:${NAME}>.vmem" -vmem 32
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we remove this file so that we don't accidentally use the non-scrambled version?

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.

@engdoreis Do we still need unscrambled bootrom.vmem files to be built once we switch to scrambled ROM in HW?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We don't need it for anything else, so I don't mind removing it.

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, I will remove the srec_cat call in the upcoming change bundle

Copy link
Copy Markdown
Collaborator

@marnovandermaas marnovandermaas left a comment

Choose a reason for hiding this comment

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

To answer my own question the DV tests are failing:

Open failed on file "bootrom_scrambled.vmem". No such file or directory
UVM_FATAL @ *: (mem_bkdr_util.sv:658) [mem_bkdr_util[ChipMemROM]] file /home/mvdmaas/mocha/scratch/kmac/top_chip_system.sim.xcelium/*.pwr mgr_smoke/latest/bootrom_scrambled.vmem could not be opened for r mode has 1 failure

I'm marking this as request changes just to avoid us merging this, but still very much want this PR to be merged.

@elliotb-lowrisc
Copy link
Copy Markdown
Contributor Author

To answer my own question the DV tests are failing:

mocha/scratch/kmac/top_chip_system.sim.xcelium/0.pwrmgr_smoke/latest/run.log
UVM_FATAL @ *: (mem_bkdr_util.sv:658) [mem_bkdr_util[ChipMemROM]] file /home/mvdmaas/mocha/scratch/kmac/top_chip_system.sim.xcelium/*.pwr mgr_smoke/latest/bootrom_scrambled.vmem could not be opened for r mode has 1 failure

I'm marking this as request changes just to avoid us merging this, but still very much want this PR to be merged.

Yes this has been my main priority, but I hadn't got to the bottom of it yet. I evidently hadn't run a top-level UVM test as I thought I had. Fixing the filename issue reveals that alert assertions are firing in KMAC, which I'm attempting to investigate. The alerts are disconnected, so I'm guessing this is a case of something unexpectedly causing an alert to fire.

@elliotb-lowrisc
Copy link
Copy Markdown
Contributor Author

Got it. I'll include the fixes in my update to this PR later today, once I've hopefully got some other changes in to avoid churn.

### Test Results

|  Stage  |  Name  | Tests                               |  Max Job Runtime  |  Simulated Time  |  Passing  |  Total  |  Pass Rate  |
|:-------:|:------:|:------------------------------------|:-----------------:|:----------------:|:---------:|:-------:|:-----------:|
|         |        | axi_sram_smoke                      |     119.000s      |    871.125us     |     1     |    1    |  100.00 %   |
|         |        | axi_sram_smoke_cheri                |     131.000s      |    965.764us     |     1     |    1    |  100.00 %   |
|         |        | mailbox_smoke                       |     120.000s      |    880.556us     |     1     |    1    |  100.00 %   |
|         |        | test_framework_exception_test       |     145.000s      |    1449.859us    |     1     |    1    |  100.00 %   |
|         |        | uart_smoke_cheri                    |     141.000s      |    1604.901us    |     1     |    1    |  100.00 %   |
|         |        | entropy_src_smoke                   |     162.000s      |    1167.483us    |     1     |    1    |  100.00 %   |
|         |        | entropy_src_smoke_cheri             |     172.000s      |    1244.480us    |     1     |    1    |  100.00 %   |
|         |        | spi_host_smoke_cheri                |      2.134s       |     0.000us      |     0     |    1    |   0.00 %    |
|         |        | rv_timer_smoke_cheri                |     129.000s      |    1157.204us    |     1     |    1    |  100.00 %   |
|         |        | spi_device_smoke                    |     104.000s      |    853.598us     |     0     |    1    |   0.00 %    |
|         |        | spi_host_smoke                      |      2.273s       |     0.000us      |     0     |    1    |   0.00 %    |
|         |        | spi_device_smoke_cheri              |     107.000s      |    914.524us     |     0     |    1    |   0.00 %    |
|         |        | gpio_smoke                          |     121.000s      |    876.970us     |     1     |    1    |  100.00 %   |
|         |        | rv_plic_smoke_cheri                 |     137.000s      |    1000.795us    |     1     |    1    |  100.00 %   |
|         |        | uart_smoke                          |     140.000s      |    1517.149us    |     1     |    1    |  100.00 %   |
|         |        | rom_ctrl_smoke                      |      1.582s       |     0.000us      |     0     |    1    |   0.00 %    |
|         |        | gpio_smoke_cheri                    |     132.000s      |    961.722us     |     1     |    1    |  100.00 %   |
|         |        | rom_ctrl_smoke_cheri                |      1.469s       |     0.000us      |     0     |    1    |   0.00 %    |
|         |        | rstmgr_smoke                        |     217.000s      |    1670.049us    |     1     |    1    |  100.00 %   |
|         |        | rstmgr_smoke_cheri                  |     240.000s      |    1864.046us    |     1     |    1    |  100.00 %   |
|         |        | rv_timer_smoke                      |     113.000s      |    1053.471us    |     1     |    1    |  100.00 %   |
|         |        | clkmgr_smoke                        |     120.000s      |    880.313us     |     1     |    1    |  100.00 %   |
|         |        | clkmgr_smoke_cheri                  |     131.000s      |    950.961us     |     1     |    1    |  100.00 %   |
|         |        | pwrmgr_smoke                        |     120.000s      |    887.377us     |     1     |    1    |  100.00 %   |
|         |        | pwrmgr_smoke_cheri                  |     132.000s      |    956.121us     |     1     |    1    |  100.00 %   |
|         |        | rv_plic_smoke                       |     126.000s      |    912.638us     |     1     |    1    |  100.00 %   |
|         |        | rv_timer_irq                        |     154.000s      |    2159.657us    |     1     |    1    |  100.00 %   |
|         |        | rv_timer_irq_cheri                  |     157.000s      |    2259.194us    |     1     |    1    |  100.00 %   |
|         |        | test_framework_exception_test_cheri |     134.000s      |    1518.122us    |     1     |    1    |  100.00 %   |
|         |        | mailbox_smoke_cheri                 |     130.000s      |    962.910us     |     1     |    1    |  100.00 %   |
|         |        | **TOTAL**                           |                   |                  |    24     |   30    |   80.00 %   |
|         |        | **TOTAL**                           |                   |                  |    24     |   30    |   80.00 %   |

Rather than vendoring dependencies of KMAC not already in Mocha
(keymgr, edn, csrng), patch kmac_pkg.sv to include the minor
bits required from the keymgr and edn packages.
Mocha doesn't need these modules in full as we are only using
KMAC to check the contents of the scrambled ROM.

Also, fix the ROM image scrambling script import paths for Mocha.
Integrate KMAC hardware block for use with the ROM checker only.
No other KMAC interfaces are connected.

Modify the SW build system to generate a scrambled boot-ROM image.
Attempting to run an un-scrambled image will be blocked by the
in-hardware ROM checker.

Add minimal HJSON files required for ROM image scrambling script.
These use the OT testing secrets for now.
@elliotb-lowrisc
Copy link
Copy Markdown
Contributor Author

  • Rebased onto latest.
  • Removed new dependencies with a patch to kmac_pkg.sv instead.
  • Removed un-scrambled bootrom generation.
  • Fixed the copying of the scrambled bootrom VMEM file for UVM tests.
  • Fixed the default values assigned to the KMAC alert_rx port which was triggering assertions (despite being assigned exactly the same way for other modules in the Mocha top-level).

Copy link
Copy Markdown
Collaborator

@marnovandermaas marnovandermaas left a comment

Choose a reason for hiding this comment

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

Very cool, just one more comment from my end. I'll need to re-run the DV as well.

// Unused Interfaces
.tl_i (tlul_pkg::TL_H2D_DEFAULT),
.tl_o ( ),
.alert_rx_i ({prim_alert_pkg::ALERT_RX_DEFAULT, prim_alert_pkg::ALERT_RX_DEFAULT}),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Instead of repeating can we use something like:
'{default: prim_alert_pkg::ALERT_RX_DEFAULT}
We should probably replace that in all the other places as well because alert_rx_i is an array in all OpenTitan blocks, even if most of them only have one alert.

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.

Funny you should suggest that, because that's exactly what I did in my first set of changes. Unfortunately, that resulted in the top-level UVM tests failing due to an alert assertion firing in KMAC due to incorrectly assigned alert_rx signals (both _n and _p high). I still don't understand why the '{default: ...} structure causes problems for kmac but not e.g. rstmgr despite using the exact same interface. I'll continue investigating now I know this duplication is something you want to avoid.

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.

@marnovandermaas It seems using a type-key rather than the default-key works:

    .alert_rx_i        ('{prim_alert_pkg::alert_rx_t: prim_alert_pkg::ALERT_RX_DEFAULT}),

This avoids duplication, while being more specific about the members to assign.

Would this be an acceptable solution for you?

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.

Nevermind, Verilator doesn't like it

@marnovandermaas marnovandermaas dismissed their stale review June 5, 2026 10:30

Top-level DV is now passing with the latest changes.

@elliotb-lowrisc
Copy link
Copy Markdown
Contributor Author

How clever I thought myself, to use a nifty SystemVerilog feature.
"What!" cried Verilator, "I reject such a creature!"

Copy link
Copy Markdown
Contributor

@ziuziakowska ziuziakowska left a comment

Choose a reason for hiding this comment

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

I'm happy with the SW side.

@elliotb-lowrisc elliotb-lowrisc merged commit 4fbccfe into lowRISC:main Jun 5, 2026
10 checks passed
@elliotb-lowrisc elliotb-lowrisc deleted the kmac branch June 5, 2026 10:49
@elliotb-lowrisc elliotb-lowrisc linked an issue Jun 5, 2026 that may be closed by this pull request
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.

Integrate SW scrambling script and merge along with HW changes

4 participants