Skip to content

Commit

Permalink
[manuf] refactor FT flows to enable downstream OTP definitions
Browse files Browse the repository at this point in the history
This refactors the FT provisioning Bazel build binary and test targets
to enable defining downstream OTP configurations and ingesting them into
FT provisioning flows.

Additionally, this removes the reliance on build configurations to
select which personalization extension to use, and simply builds and
tests all FT provisioning flows that can be enumerated at build time.
This makes it easier to run and test all flows upstream only, with:
`bazel test //sw/device/silicon_creator/manuf/base:ft_provision_cw310`,
or all flows upstream and downstream with:
`PROV_EXTS_DIR=... bazel test //sw/device/silicon_creator/manuf/base:ft_provision_cw310`.
As a result, this also simplifies the build graph by removing
configuration transistions.

Signed-off-by: Tim Trippel <[email protected]>
(cherry picked from commit 87e0070)
  • Loading branch information
timothytrippel authored and github-actions[bot] committed Oct 30, 2024
1 parent 4cdfb5d commit de283f7
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 191 deletions.
2 changes: 1 addition & 1 deletion rules/otp.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ otp_image_consts = rule(
# keys. This is useful for testing in dv_sim, fpga and verilator
# environments.
OTP_SIGVERIFY_FAKE_KEYS = [
"//sw/device/silicon_creator/rom/keys/fake/otp:json_rot_keys",
"@//sw/device/silicon_creator/rom/keys/fake/otp:json_rot_keys",
]

# This is a set of overlays to generate a generic, standard OTP image.
Expand Down
21 changes: 6 additions & 15 deletions sw/device/silicon_creator/manuf/base/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,15 @@ opentitan_test(
"//sw/device/silicon_creator/manuf/lib:individualize_sw_cfg_{}".format(cfg),
],
)
for cfg in EARLGREY_OTP_CFGS
for cfg in EARLGREY_OTP_CFGS.keys()
]

filegroup(
name = "sram_ft_individualize_all",
testonly = True,
srcs = [
":sram_ft_individualize_{}".format(cfg)
for cfg in EARLGREY_OTP_CFGS
for cfg in EARLGREY_OTP_CFGS.keys()
],
)

Expand Down Expand Up @@ -322,20 +322,11 @@ manifest(d = {
"//sw/device/silicon_creator/manuf/lib:flash_info_fields",
"//sw/device/silicon_creator/manuf/lib:individualize_sw_cfg_{}".format(config["otp"]),
"//sw/device/silicon_creator/manuf/lib:personalize",
] + config["dice_libs"] + config["ext_libs"],
] + config["dice_libs"] + config["device_ext_libs"],
)
for sku, config in EARLGREY_SKUS.items()
]

filegroup(
name = "ft_personalize_all",
testonly = True,
srcs = [
":ft_personalize_{}".format(sku)
for sku in EARLGREY_SKUS.keys()
],
)

config_setting(
name = "ckms_cert_endorsement_params",
flag_values = {":endorse_certs_with_ckms": "True"},
Expand All @@ -354,7 +345,7 @@ _FT_PROVISIONING_CMD_ARGS = """
"//conditions:default": LOCAL_CERT_ENDORSEMENT_PARAMS,
})

_FT_PROVISIONING_HARNESS = "//sw/host/provisioning/ft"
_FT_PROVISIONING_HARNESS = "//sw/host/provisioning/ft:ft_{}"

[
opentitan_test(
Expand All @@ -380,7 +371,7 @@ _FT_PROVISIONING_HARNESS = "//sw/host/provisioning/ft"
"manuf",
],
test_cmd = _FT_PROVISIONING_CMD_ARGS,
test_harness = _FT_PROVISIONING_HARNESS,
test_harness = _FT_PROVISIONING_HARNESS.format(sku),
),
silicon = silicon_params(
binaries =
Expand All @@ -393,7 +384,7 @@ _FT_PROVISIONING_HARNESS = "//sw/host/provisioning/ft"
interface = "teacup",
needs_jtag = True,
test_cmd = _FT_PROVISIONING_CMD_ARGS,
test_harness = _FT_PROVISIONING_HARNESS,
test_harness = _FT_PROVISIONING_HARNESS.format(sku),
),
)
for sku, config in EARLGREY_SKUS.items()
Expand Down
34 changes: 25 additions & 9 deletions sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,45 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

EARLGREY_OTP_CFGS = [
"sival",
"prodc",
]
load(
"@provisioning_exts//:cfg.bzl",
"EXT_EARLGREY_OTP_CFGS",
"EXT_EARLGREY_SKUS",
)

# A list of OTP configurations that will be used to autogenerate FT
# individualization binaries that configure OTP with the constants defined in
# these bazel targets.
EARLGREY_OTP_CFGS = {
"sival": "//hw/ip/otp_ctrl/data/earlgrey_skus/sival:otp_consts",
"prodc": "//hw/ip/otp_ctrl/data/earlgrey_skus/prodc:otp_consts",
} | EXT_EARLGREY_OTP_CFGS

# A dictionary of SKU configurations that will be used to generate FT
# personalization binaries that configure OTP and flash info pages as defined
# in these bazel targets.
EARLGREY_SKUS = {
# OTP Config: SIVAL; DICE Certs: X.509; Additional Certs: None
"sival": {
"otp": "sival",
"dice_libs": ["//sw/device/silicon_creator/lib/cert:dice"],
"ext_libs": ["@provisioning_exts//:perso_fw_ext"],
"host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"],
"device_ext_libs": ["@provisioning_exts//:default_perso_fw_ext"],
},
# OTP Config: SIVAL; DICE Certs: CWT; Additional Certs: None
# TODO(#24281): uncomment when DICE CWT cert flows are fully supported
# "sival_dice_cwt": {
# "otp": "sival",
# "dice_libs": ["//sw/device/silicon_creator/lib/cert:dice_cwt"],
# "ext_libs": ["@provisioning_exts//:perso_fw_ext"],
# "host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"],
# "device_ext_libs": ["@provisioning_exts//:default_perso_fw_ext"],
# },
# OTP Config: SIVAL; DICE Certs: X.509; Additional Certs: TPM EK
"sival_tpm": {
"otp": "sival",
"dice_libs": ["//sw/device/silicon_creator/lib/cert:dice"],
"ext_libs": [
"host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"],
"device_ext_libs": [
"//sw/device/silicon_creator/lib/cert:tpm_ek_template_library",
"//sw/device/silicon_creator/manuf/base:tpm_perso_fw_ext",
],
Expand All @@ -34,9 +49,10 @@ EARLGREY_SKUS = {
"prodc": {
"otp": "prodc",
"dice_libs": ["//sw/device/silicon_creator/lib/cert:dice"],
"ext_libs": ["@provisioning_exts//:perso_fw_ext"],
"host_ext_libs": ["@provisioning_exts//:default_ft_ext_lib"],
"device_ext_libs": ["@provisioning_exts//:default_perso_fw_ext"],
},
}
} | EXT_EARLGREY_SKUS

_DEVICE_ID_AND_TEST_TOKENS = """
--device-id="0x11111111_22222222_33333333_44444444_55555555_66666666_77777777_88888888"
Expand Down
49 changes: 0 additions & 49 deletions sw/device/silicon_creator/manuf/extensions/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,10 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@rules_rust//rust:defs.bzl", "rust_library")

package(default_visibility = ["//visibility:public"])

bool_flag(
name = "use_example_perso_ext",
build_setting_default = False,
)

config_setting(
name = "example_perso_ext_cfg",
flag_values = {
":use_example_perso_ext": "True",
},
)

cc_library(
name = "example_perso_fw_ext",
srcs = ["example_personalize_ext.c"],
deps = [
"@//sw/device/lib/dif:flash_ctrl",
"@//sw/device/lib/runtime:log",
"@//sw/device/lib/testing/json:provisioning_data",
"@//sw/device/lib/testing/test_framework:status",
"@//sw/device/lib/testing/test_framework:ujson_ottf",
"@//sw/device/silicon_creator/lib/cert",
"@//sw/device/silicon_creator/manuf/base:personalize_ext",
"@//sw/device/silicon_creator/manuf/lib:flash_info_fields",
],
)

cc_library(
name = "default_perso_fw_ext",
srcs = ["default_personalize_ext.c"],
Expand All @@ -48,16 +20,6 @@ cc_library(
],
)

_DEVICE_PERSO_EXTS = select({
"example_perso_ext_cfg": [":example_perso_fw_ext"],
"//conditions:default": [":default_perso_fw_ext"],
})

cc_library(
name = "perso_fw_ext",
deps = _DEVICE_PERSO_EXTS,
)

rust_library(
name = "default_ft_ext_lib",
srcs = ["default_ft_ext_lib.rs"],
Expand All @@ -67,14 +29,3 @@ rust_library(
"@crate_index//:arrayvec",
],
)

rust_library(
name = "example_ft_ext_lib",
srcs = ["example_ft_ext_lib.rs"],
crate_name = "ft_ext_lib",
deps = [
"@crate_index//:anyhow",
"@crate_index//:arrayvec",
"@crate_index//:log",
],
)
80 changes: 50 additions & 30 deletions sw/device/silicon_creator/manuf/extensions/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,55 @@
# Provisioning Flow Extensions

Various components of the reference provisioning flow provided can be extended
to satisfy the requirements of various SKUs. This describes the infrastructure
in place that enables extending reference provisioning flows with code managed
outside this repo.
Provisioning an Earlgrey chip requires executing code on devivce during two core
phases:
1. Chip Probe (CP): when the wafer is still intact, and
2. Final Test (FT): when each chip has been packaged and loaded into a socket.
For the most part, the CP process is the same across all Earlgrey chips,
regardless of the SKU. However, the FT process can differ based on the target
SKU.

## FT Provisioning Overview

There are two main phases during FT provisioning:
1. individualization, and
2. personalization.

## Customizing FT Provisioning Flows

Various components of the reference FT provisioning flow can be extended to
satisfy the requirements of various SKUs. Specifically, there is Bazel
infrastructure, and example code, in place to demonstrate how one can define:
1. downstream OTP configurations for a custom SKU, and
2. downstream personalization firmware and host harness extensions for a custom SKU.

Defining both start by defining an additional Bazel repo location on your system
that resembles the directory this README.md is located in, and pointing Bazel
at it via the `PROV_EXTS_DIR` envar. This tells Bazel to instantiate a local
repo called `@provisioning_exts`.

## OTP Image Definitions

To define additional OTP configurations downstream, one must add OTP targets
to the `EXT_EARLGREY_OTP_CFGS` and `EXT_EARLGREY_SKUS` dictionaries in their
downstream `@provisioning_exts` Bazel repo.

## Personalization Firmware

The personalization firmware `ft_personalize.c` defines an `extern` extension
function that is invoked as the final step in the personalization flow.

`status_t personalize_extension(ujson_t *uj)`

The example function provided in this example external Bazel repo does nothing,
except print a message to the console. However, this provides a mechanism for
SKU owners / customers to develop closed-source personalization FW extensions,
that can easily make use of open-source code.

This feature is implemented with the help of some custom Bazel repository rules.
Specifically, in this directory we define a secondary Bazel
repository (`@perso_exts`) that is designed to be used in
conjunction with the main OpenTitan Bazel repository. Within this repository, we
define a single `perso_ext` library that is linked with the reference
`ft_personalize` binary. The `perso_ext` library itself just contains an
implementation of the `personalize_extension(...)` function described above.
However, the `perso_ext` library is linked with other libraries
based on a Bazel `config_setting` that allows you to toggle which personalize
extension library should be used (if you are building binaries for several SKU
owners).

Note, the Bazel configuration settings and example personalization extension
library (`perso_ext`) provided in this
repository are merely examples, as the `personalize_extension(...)` function
implemented does nothing, except print a message.
The personalization firmware `ft_personalize.c` defines two `extern` C functions
that are invoked before and after certificates are endorsed off-device,
respectively:
`status_t personalize_extension_pre_cert_endorse(...)`
`status_t personalize_extension_post_cert_endorse(...)`

Additionally, the FT provisioning test harness provides an hook function to call
during the certificate endorsement operation:
`pub fn ft_ext(endorsed_cert_concat: ArrayVec<u8, 4096>) -> Result<ArrayVec<u8, 4096>>`

The default functions provided in this example external Bazel repo do nothing.
However, this provides a mechanism for SKU owners / customers to develop
closed-source personalization FW extensions, that can make use of open-source
code.

To configure a SKU to use downstream hooks, on must update their SKUs
configuration definition in the `EXT_EARLGREY_SKUS` dictionary in the
`@provisioning_exts` repo.
26 changes: 22 additions & 4 deletions sw/device/silicon_creator/manuf/extensions/cfg.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,25 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

HOST_FT_EXTS = select({
"@provisioning_exts//:example_perso_ext_cfg": ["@provisioning_exts//:example_ft_ext_lib"],
"//conditions:default": ["@provisioning_exts//:default_ft_ext_lib"],
})
# This enables downstream integrators to define external Earlgrey OTP
# configurations to be used during provisioning for downstream SKUs. See the
# upstream Earlgrey OTP configurations list defined in the `EARLGREY_OTP_CFGS`
# dict in `sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl` for
# more details.
EXT_EARLGREY_OTP_CFGS = {
# <OTP image name>: <//bazel/target/path:otp_image_consts>
}

# This enables downstream integrators to define external Earlgrey SKU
# configurations to be used during provisioning. See the upstream Earlgrey SKU
# configurations defined in the `EARLGREY_SKUS` dictionary in
# `sw/device/silicon_creator/manuf/base/provisioning_inputs.bzl` for more
# details.
EXT_EARLGREY_SKUS = {
# <SKU name>: {
# "otp": <OTP image name above in EXT_EARLGREY_OTP_CFGS>,
# "dice_libs": [<which DICE certgen libs to use: X.509 or CWT>]
# "host_ext_libs": [<which host hooks extension libraries to use>]
# "device_ext_libs": [<which device hooks extension libraries to use>]
# }
}
11 changes: 0 additions & 11 deletions sw/device/silicon_creator/manuf/extensions/example_ft_ext_lib.rs

This file was deleted.

This file was deleted.

4 changes: 2 additions & 2 deletions sw/device/silicon_creator/manuf/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ cc_library(
name = "individualize_sw_cfg_{}".format(cfg),
deps = [
":individualize_sw_cfg",
"//hw/ip/otp_ctrl/data/earlgrey_skus/{}:otp_consts".format(cfg),
"{}".format(target),
],
)
for cfg in EARLGREY_OTP_CFGS
for cfg, target in EARLGREY_OTP_CFGS.items()
]

opentitan_test(
Expand Down
Loading

0 comments on commit de283f7

Please sign in to comment.