-
Notifications
You must be signed in to change notification settings - Fork 792
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
RFC: Initial ROM vendor hooks implementation #25642
base: master
Are you sure you want to change the base?
Changes from all commits
50716f4
d28c148
98b8f28
0c9846e
eebb5e4
7b41f03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
--- | ||
Document: RFC | ||
Title: ROM Vendor Customizations | ||
Status: Draft | ||
Authors: Samuel Ortiz <[email protected]> | ||
Reviewers: | ||
--- | ||
|
||
# RFC: ROM Vendor Customizations | ||
|
||
## Problem Statement | ||
|
||
Currently, OpenTitan mask ROM implementations lack customization options for silicon creators and vendors. While discrete OpenTitan ROMs can be directly built upon the [upstream implementation](https://github.com/lowRISC/opentitan/tree/master/sw/device/silicon_creator/rom), the same isn't true for integrated OpenTitan top ROMs. | ||
|
||
Integrated OpenTitan ROMs configure, initialize, and interact with external subsystems specific to the platform. These interactions often vary between vendors and platform variants. A single, fixed ROM implementation prevents downstream silicon creators and vendors from directly utilizing the upstream code, forcing them to fork the project and maintain custom versions internally. | ||
|
||
## Requirements | ||
|
||
To enable direct vendor contribution and consumption of OpenTitan upstream ROM implementations, the project architecture and source code for ROMs must meet the following requirements: | ||
|
||
1. Vendor customization: OpenTitan ROM code should allow silicon creators and vendors to customize the upstream ROM execution flow with vendor-specific initialization and configuration sequences. | ||
2. Controlled customization points: OpenTitan ROMs should be customizable at specific, predefined execution points. Vendors can only modify ROM behavior at these designated points. | ||
3. Support for closed-source customization: The OpenTitan ROM build infrastructure should support linking ROM images with externally stored, vendor-specific customization code, allowing vendors to keep their customizations private. | ||
4. Attestation: Silicon creators and vendors should provide endorsed reference values for their customized OpenTitan ROMs, including the ROM version and its associated hash. Out-of-band verifiers can then compare these values with the ROM's generated attestation reports. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @moidx |
||
5. Default functionality: By default, OpenTitan ROMs should function without any vendor-specific customizations. | ||
|
||
## Proposed Approach | ||
|
||
At a high level, the proposed solution involves implementing an OpenTitan ROM as a state machine. Each state in this state machine is semantically defined by the upstream ROM code and represents a customizable execution step. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment from @modix in #25633 (comment): State machine considerations: We are still working on evaluating the effectiveness of hardware countermeasures with respect to fault attacks. Until then, we recommend to maintain the level of hardening present in the upstream version of the ROM. In practice, it is very difficult to harden code with too many branches. Ideally, we should aim as much as possible to maintain a linear execution sequence. I propose we define a requirement to cover this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
One interesting side effect of defining the ROM as a state machine is that you can systematically include CFI within the state machine walking routine. I have a pending patch to show this in practice, but the idea is that each ROM state would be protected by its implicit CFI counter so that the ROM state machine flow is controlled.
That makes sense, yes. To be clear here, the current ROM is not linear and has many branches, mostly for error handling but also for the bootstrap and immutable ROM extension flows for example. If anything, I feel that explicitly defining the ROM as a state machine would allow for more easily tracking those branches than the current implementation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As @Razer6 pointed out privately, with an actual state machine we might be able to more easily enforce that ROM states functions are actually linear (except for error paths) and branches are the state machine transitions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I added a couple of commits to this PR to illustrate how CFI counters could be inserted in the ROM state machine walker. |
||
|
||
As the ROM progresses through its state machine, it executes the current state and then transitions to the next one. A state execution consists of the following three sequential steps: | ||
|
||
1. Pre-run Hook: Executed before the primary ROM state function. | ||
2. ROM State Run: The core execution of the ROM state. | ||
3. Post-run Hook: Executed after the primary ROM state function. | ||
|
||
By structuring the ROM as a state machine with these hooks, vendors can customize the ROM's behavior at specific points without modifying the upstream ROM code. | ||
|
||
``` | ||
Initial | ||
┌ROM State───┐ | ||
│ ┌────────┐ │ | ||
│ │Pre-run │ │ | ||
│ ├────────┤ │ | ||
│ │ Run │ │ | ||
│ ├────────┤ │ | ||
│ │Post-run│ │ | ||
│ └────────┘ │ | ||
└──────┬─────┘ | ||
ROM ┌─────────┴─────────┐ ROM | ||
┌State─▽─────┐ ┌──────▽──State | ||
│ ┌────────┐ │ │ ┌────────┐ │ | ||
│ │Pre-run │ │ │ │Pre-run │ │ | ||
│ ├────────┤ │ │ ├────────┤ │ | ||
│ │ Run │ │ │ │ Run │ │ | ||
│ ├────────┤ │ │ ├────────┤ │ | ||
│ │Post-run│ │ │ │Post-run│ │ | ||
│ └────────┘ │ │ └────────┘ │ | ||
└────────────┘ └──────┬─────┘ | ||
│ ROM | ||
┌──────▽──State | ||
│ ┌────────┐ │ | ||
│ │Pre-run │ │ | ||
│ ├────────┤ │ | ||
│ │ Run │ │ | ||
│ ├────────┤ │ | ||
│ │Post-run│ │ | ||
│ └────────┘ │ | ||
└────────────┘ | ||
``` | ||
|
||
With this proposal, vendors can customize an OpenTitan ROM by providing custom implementations for the pre-run and post-run hooks of any ROM state. By default, these hooks are empty. | ||
|
||
The main ROM state implementation, the run callback, is executed in step 2. All ROM state run callbacks are defined by the upstream ROM implementation and are not customizable. | ||
|
||
Crucially, only the run callback determines the next state in the ROM state machine. Pre-run and post-run hooks cannot override these transitions, preventing vendors from directly modifying the ROM's execution flow. | ||
|
||
In essence, this proposal enables vendors to customize the execution of individual ROM states, but it strictly controls the overall ROM execution flow. | ||
|
||
### ROM states | ||
|
||
Each OpenTitan ROM defines a set of execution states and associates each state with a specific ROM state run callback. A ROM state run callback takes an opaque pointer argument (which is shared with the state hooks) and returns the next state in the sequence. | ||
|
||
To enable effective vendor customization, ROM states should be clearly defined and map to specific functional steps in the ROM's execution flow. For instance, `kRomStateBootstrap` is a well-defined state, while `kRomStateStep3` is too generic. | ||
|
||
The more precisely a ROM state is defined, the easier it is for vendors to understand and customize its behavior. | ||
|
||
### ROM state hooks | ||
|
||
Pre-run and post-run ROM state hooks are executed by the ROM state machine before and after each state run callback, respectively. They share state with the state run callbacks through an opaque pointer argument. | ||
|
||
Unlike the state run callback, ROM state hooks cannot determine the next state in the ROM state machine. Vendors can customize specific ROM state execution steps through these hooks by providing custom implementations in an external repository. | ||
|
||
Similar to the existing manufacturing and test hook customization framework, custom ROM state hooks can be included in a ROM image by specifying the path to the vendor hook implementations in an environment variable passed to the ROM build system: | ||
|
||
``` bash | ||
ROM_HOOKS_DIR=/PATH/TO/LOCAL/ROM/HOOKS ./bazelisk.sh build //sw/device/silicon_creator/rom:mask_rom | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment from @a-will in #25633 (comment): Just an implementation nit: It would be nice if we could avoid more environment variable dependencies. Perhaps bazel's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment from @moidx in #25633 (comment): We should look at all existing integration hooks (1. closed source There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. As @a-will proposed, we could look at using Bazel's module override and make all external hooks expose themselves as an external module to OpenTitan. |
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Copyright lowRISC contributors (OpenTitan project). | ||
# Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
cc_library( | ||
name = "rom_hooks", | ||
srcs = ["dummy_rom_hooks.c"], | ||
deps = ["@//sw/device/silicon_creator/rom:rom_state"], | ||
alwayslink = True, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment from @moidx in #25633 (comment):
Are we planning to define additional requirements for out of band verification? For example, can we ask silicon integrators to document the expected ROM version and associated hash for any given silicon release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am expecting a device attestation report to include its boot ROM hash, and that could be used by a verifier against a set of reference values that thus would need to include the expected ROM hash and version. Those reference values are typically built and signed by the silicon creators, so this is even more than just documenting.
Also, this should already be a requirement today, independent of this RFC proposal here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment from @moidx in #25633 (comment):
Hi @sameo, I brought this up because in cases where there are no customization hooks, the verifier can perform an out of band check by building the ROM from source. I understand that the out of band measurement is a requirement from the verifier's perspective, but thought it would be good to have this included in the documentation. Mentioning that this is covered by an attestation report is sufficient from my perspective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @moidx. I see, this makes sense.
I added an additional attestation requirement to address that one.