[perso_fw] Remove all_certs buffer in ft_personalize.c - #31038
Open
xorptr wants to merge 22 commits into
Open
Conversation
…blob_v1 target Remove the blob_version attribute from the sku_cfg Bazel rule, the SkuConfig Python dataclass, and the ot_dut.py CLI builder, and remove the unused emulation_blob_v1 target from BUILD and provisioning_inputs.bzl. TAG=agy CONV=f24c5c61-71d1-4fc3-aef0-af78d1125515 Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com> Change-Id: If644fb28344e83937ccd261bb241a2de6a6a6964
… FT tool Add per-object TLV format version detection and construction to perso_tlv_lib. Update ObjHeader with header_size and version, add MAX_CERT_NAME_LEN and MAX_CERT_LEN constants to PersoTlvTypes, and update ft_lib to use PersoBlobParser::new() and PersoBlobBuilder::new(). TAG=agy CONV=f24c5c61-71d1-4fc3-aef0-af78d1125515 Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com> Change-Id: I9d1871e5ad93152b80a7d13725f27e146a6a6964
…ary and firmware Add 4-byte V1 version prefix (0x010004F0) handling to device perso_tlv_data. Update perso_tlv_get_cert_obj, perso_tlv_object_type, and perso_tlv_object_size to detect object version from buffer without external blob_version arguments. Update ft_personalize.c and test callers accordingly. TAG=agy CONV=f24c5c61-71d1-4fc3-aef0-af78d1125515 Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com> Change-Id: I0db63e5d5adf3fa35d9a95fd0bceb4296a6a6964
Remove the blob_version field from manuf_certgen_inputs_t ujson struct and test harnesses, and remove the BlobVersion enum and --blob-version CLI argument from sw/host/provisioning/ft. TAG=agy CONV=f24c5c61-71d1-4fc3-aef0-af78d1125515 Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com> Change-Id: I7cad734f7db2b98202d1405052ad71236a6a6964
xorptr
force-pushed
the
perso_ft_provisioning_reduce_sram_usage_remove_all_certs_buffer
branch
from
August 18, 2026 05:58
57c0137 to
0da5909
Compare
sasdf
approved these changes
Aug 18, 2026
| @@ -834,14 +833,13 @@ static size_t max_available(const perso_blob_t *blob) { | |||
| * Find the next certificate perso LTV object in the receive perso buffer and | |||
| * copy it to the passed in location. | |||
Contributor
There was a problem hiding this comment.
maybe edit this line since it no longer copies?
Currently, the firmware stores number of objects in perso blob from host after extracting the "UDS" certificate. There may or may not be object present before the "UDS" certificate TLV object. Then the firmware changes the `num_objs` in `perso_blob_from_host`, and later restores it from the temporary variable initialized after extracting the "UDS" certificate. This commit changes the behavior to store the number of objects received from the host in perso blob just after receiving the blob Signed-off-by: Lovepreet Singh <lpsingh@google.com> (cherry picked from commit 0d6d1c0)
Prefix the ML-DSA certificate in data flash with the 4-byte V1 version object (kPersoTlvVersionPrefixV1 = 0x010004F0). Null-pad the name array to 12 bytes for "PQ_CDI_0" and "PQ_CDI_1" and set the cert header name length to 12 to produce a 24-byte header (a multiple of 8 for flash write alignment). TAG=agy CONV=f24c5c61-71d1-4fc3-aef0-af78d1125515 Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com> Change-Id: I00567f31f224981bfe09ec87475ebdd16a6a6964
…ped static variables This commits moves most of the global static variables into function local scope. The motive behind this refactor is to allow better reason about the liveness of these variables when doing future changes to this code. The declarations are pushed as deep in the call chain as possible based on how the variables are used currently - I removed `static` qualifier from `uds_key_ids` and `cdi_0_key_ids` since the compiler could not statically initialize fields with `uds_pubkey_id` (because now it is an input to the function) - I added checks for size of `all_certs` against max size of DICE certificates. This should not cause any behavior change since `all_certs` is statically allocated to be much larger than max size of DICE certificates - I removed `orig_num_objects_from_host`. Instead the function now has a local variable to temporarily store the original count, and the count is restored before the function returns Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 18.6% 30.4Ki .bss NAN% 0 26.4% 8.00Ki provision.all_certs NAN% 0 16.5% 5.01Ki provision.blob_from_host NAN% 0 16.5% 5.01Ki provision.blob_to_host NAN% 0 13.2% 4.00Ki owner_page NAN% 0 6.6% 2.00Ki personalize_endorse_certificates.dice_page NAN% 0 6.5% 1.97Ki main_spi_buf NAN% 0 3.3% 1024 hash_certificate.cert_buffer NAN% 0 2.3% 708 measure_otp_partition.otp_state NAN% 0 1.9% 588 cdi_1_tbs_buffer NAN% 0 1.6% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.7% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 64 personalize_gen_dice_certificates.cdi_0_pubkey NAN% 0 0.2% 64 personalize_gen_dice_certificates.curr_pubkey NAN% 0 0.2% 64 provision.uds_pubkey NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 provision.certgen_inputs NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 32 personalize_gen_dice_certificates.attestation_binding_value NAN% 0 0.1% 32 personalize_gen_dice_certificates.cdi_0_pubkey_id NAN% 0 0.1% 32 personalize_gen_dice_certificates.cdi_1_pubkey_id NAN% 0 0.1% 32 personalize_gen_dice_certificates.sealing_binding_value NAN% 0 0.1% 32 personalize_gen_dice_certificates.uds_endorsement_key_id NAN% 0 0.1% 32 personalize_gen_dice_certificates.zero_digest NAN% 0 0.1% 32 provision.otp_creator_sw_cfg_measurement NAN% 0 0.1% 32 provision.otp_owner_sw_cfg_measurement NAN% 0 0.1% 32 provision.otp_rot_creator_auth_codesign_measurement NAN% 0 0.1% 32 provision.otp_rot_creator_auth_state_measurement NAN% 0 0.1% 32 provision.uds_pubkey_id ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
This commit removes `static` qualifier from few static variables which were moved to function scope in the previous commit. I arbitraily chose 32 bytes as the limit so as to not increase the total stack usage while also reducing a little bit of `.bss` section use. The stack variables are zero-initialized as they were earlier when they were static Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 18.5% 30.1Ki .bss NAN% 0 26.6% 8.00Ki provision.all_certs NAN% 0 16.7% 5.01Ki provision.blob_from_host NAN% 0 16.7% 5.01Ki provision.blob_to_host NAN% 0 13.3% 4.00Ki owner_page NAN% 0 6.7% 2.00Ki personalize_endorse_certificates.dice_page NAN% 0 6.6% 1.97Ki main_spi_buf NAN% 0 3.3% 1024 hash_certificate.cert_buffer NAN% 0 2.3% 704 measure_otp_partition.otp_state NAN% 0 1.9% 588 cdi_1_tbs_buffer NAN% 0 1.6% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.7% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 64 personalize_gen_dice_certificates.cdi_0_pubkey NAN% 0 0.2% 64 personalize_gen_dice_certificates.curr_pubkey NAN% 0 0.2% 64 provision.uds_pubkey NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 provision.certgen_inputs NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 32 personalize_gen_dice_certificates.attestation_binding_value NAN% 0 0.1% 32 personalize_gen_dice_certificates.sealing_binding_value ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
This commits makes appropriate function parameters `const` qualified. The motive behind this change is to make it easier to reason about mutability of the static variables left in the previous commit. A notable refactor in this commit is change from `perso_tlv_get_cert_obj` to `perso_tlv_get_cert_obj_view`. The new function now returns `perso_tlv_cert_obj_view_t` instead of `perso_tlv_cert_obj_t`. `perso_tlv_cert_obj_view_t` is similar to `perso_tlv_cert_obj_t`, but internally it uses const pointers to the underlying buffer (hence giving only immutable access/view to the underlying buffer). This allows making the buffer passed to `perso_tlv_get_cert_obj_view` `const` qualified, which in turn helps confirm that `personalize_endorse_certificates` uses `blob_to_host` only for reads. I also changes `zero_digest` to `const static` so that it can be moved to `.rodata` Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 18.5% 30.1Ki .bss NAN% 0 26.6% 8.00Ki provision.all_certs NAN% 0 16.7% 5.01Ki provision.blob_from_host NAN% 0 16.7% 5.01Ki provision.blob_to_host NAN% 0 13.3% 4.00Ki owner_page NAN% 0 6.7% 2.00Ki personalize_endorse_certificates.dice_page NAN% 0 6.6% 1.97Ki main_spi_buf NAN% 0 3.3% 1024 hash_certificate.cert_buffer NAN% 0 2.3% 704 measure_otp_partition.otp_state NAN% 0 1.9% 588 cdi_1_tbs_buffer NAN% 0 1.6% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.7% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 64 personalize_gen_dice_certificates.cdi_0_pubkey NAN% 0 0.2% 64 personalize_gen_dice_certificates.curr_pubkey NAN% 0 0.2% 64 provision.uds_pubkey NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 provision.certgen_inputs NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 32 personalize_gen_dice_certificates.attestation_binding_value NAN% 0 0.1% 32 personalize_gen_dice_certificates.sealing_binding_value ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
…chain This commit moves the static variables that were not marked with `const` qualifier up in the call chain. I have moved them to the function where the 2 major stages of provisioning occur: pre-endorsement and post-endorsement. The motive behind this changes is to (in the future) split the variables into different sets based on which stages use them I also added 2 types `cert_scratch_buffer_t` and `aligned_dice_storage_page_t` so that the alignment requirement on `cert_buffer` and `dice_page` can be expressed in function parameters until it is not needed anymore Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 18.5% 30.1Ki .bss NAN% 0 26.6% 8.00Ki provision.all_certs NAN% 0 16.7% 5.01Ki provision.blob_from_host NAN% 0 16.7% 5.01Ki provision.blob_to_host NAN% 0 13.3% 4.00Ki owner_page NAN% 0 6.7% 2.00Ki provision.dice_page NAN% 0 6.6% 1.97Ki main_spi_buf NAN% 0 3.3% 1024 provision.cert_buffer NAN% 0 2.3% 704 provision.otp_state NAN% 0 1.9% 588 cdi_1_tbs_buffer NAN% 0 1.6% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.7% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 64 provision.cdi_0_pubkey NAN% 0 0.2% 64 provision.curr_pubkey NAN% 0 0.2% 64 provision.uds_pubkey NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 provision.certgen_inputs NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 32 provision.attestation_binding_value NAN% 0 0.1% 32 provision.sealing_binding_value ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
This commit splits the static variables moved up the call chain in the previous commit. The variables are split into 2 categories at first level: variables that are used by both pre-endorsement and post-endorsement stages, and variables that are used by only one of those stages. The variables used only by one stage are put into a union to save space in SRAM. Since the stages occur one after another, only the stage specific and shared variables need to be live for a given stage. **NOTE: This optimization assumes that `personalize_extension_pre_cert_endorse` does not store any references to the pre-endorsement stage specific data after the call ends.** Since the underlying buffer will be re-used for post endorsement specific data, the data pointed to by such references will get invalidated. Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 18.3% 29.8Ki .bss NAN% 0 72.9% 21.7Ki provision.perso_data NAN% 0 13.4% 4.00Ki owner_page NAN% 0 6.6% 1.97Ki main_spi_buf NAN% 0 1.9% 588 cdi_1_tbs_buffer NAN% 0 1.6% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.7% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 24 rand_testutils_rng_ctx ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
This commit changes the function signatures to reduce the number of parameters. In the previous commit, the functions had too many parameters and many parameters had the same type. So a simple mistake such as swapping 2 parameters in the long list would be hard to detect. With a smaller list and different types for parameters where possible, such mistakes could be avoided. New types are also added to help with reducing the parameters count. Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 18.3% 29.8Ki .bss NAN% 0 72.9% 21.7Ki provision.perso_data NAN% 0 13.4% 4.00Ki owner_page NAN% 0 6.6% 1.97Ki main_spi_buf NAN% 0 1.9% 588 cdi_1_tbs_buffer NAN% 0 1.6% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.7% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 24 rand_testutils_rng_ctx NAN% 0 0.1% 20 xDelayedTaskList1 ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
… in union Based on the observation that `dice_page` and `certs_buffer` are not live together, this commit further splits post-endorsement stage specific static variables into 2 groups and puts them into a union. This saves a little bit more space in `.bss` section. Size for few entries in `.bss` section from `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 17.8% 28.8Ki .bss NAN% 0 72.0% 20.7Ki provision.perso_data NAN% 0 13.9% 4.00Ki owner_page NAN% 0 6.9% 1.97Ki main_spi_buf NAN% 0 2.0% 588 cdi_1_tbs_buffer NAN% 0 1.7% 488 cdi_0_tbs_buffer NAN% 0 0.9% 272 ottf_console_spi_getc.info NAN% 0 0.8% 224 otbn_boot_attestation_key_clear.dmem_backup NAN% 0 0.3% 100 pxReadyTasksLists NAN% 0 0.2% 64 curr_tbs_signature NAN% 0 0.2% 52 main_console NAN% 0 0.1% 40 status_report_list NAN% 0 0.1% 24 rand_testutils_rng_ctx NAN% 0 0.1% 20 xDelayedTaskList1 ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
…itionals Putting statement for single line conditionals in curly braces so that someone is less likely to make a mistake when new statements are added Signed-off-by: Lovepreet Singh <lpsingh@google.com>
…provisioning This commit changes perso firmware code to NOT generate CDI_0 and CDI_1 certificates during provisioning flow. The current behavior is as follows: 1. Device generates [CDI_0](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/manuf/base/ft_personalize.c#L655-L656) and [CDI_1](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/manuf/base/ft_personalize.c#L675-L677) endorsed certificates with zeroed out digest value and sends them to the host along with the generated UDS TBS certificate 2. Host uses these endorsed certificates to [compute the hash](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/host/provisioning/ft_lib/src/lib.rs#L419-L422) of the data that device is expected to write to the flash 3. Host DOES NOT send endorsed CDI_0 and CDI_1 certificates back to the device. Host does send endorsed UDS certificate (see [code](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/host/provisioning/ft_lib/src/lib.rs#L381)) 4. Device reads endorsed UDS certificate sent by the host for X.509, or from blob sent to the host for CWT. Device reads endorsed CDI_0 and CDI_1 certificates from blob sent to the host (see [code](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/manuf/base/ft_personalize.c#L990-L1016)) 5. Device writes endorsed UDS certificate to FACTORY page, and endorsed CDI_0 and CDI_1 certificates to DICE page (see [code](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/manuf/base/ft_personalize.c#L1059-L1084)) 6. Device [reads and hashes endorsed UDS, CDI_0, and CDI_1 certificates](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/manuf/base/ft_personalize.c#L502-L537) along with other data, and [sends them to the host](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/manuf/base/ft_personalize.c#L1230-L1231) 7. Host checks the device hash against the hash it expects (see [code](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/host/provisioning/ft_lib/src/lib.rs#L453-L475)) The new behavior is as follows: 1. Device only generates UDS TBS certificate for DICE chain and sends it to the host for endorsement 2. Host only takes into account endorsed UDS certificate (for the DICE chain) when computing the hash it expects later 3. Host sends endorsed UDS certificate back to the device 4. Device reads endorsed UDS certificate sent by the host for X.509, or from the blob sent to the host for CWT. 5. Device only writes endorsed UDS certificate (for the DICE chain) to FACTORY page 6. Device computed hash only includes endorsed UDS certificate (for the DICE chain). Device sends the computed hash to the host 7. Host checks the hash sent by the device against the hash it expects NOTES: 1. I have still kept the "DICE" page marked as "used" in the flash layout list since I am not sure if the extensions look for the first unused page to determine pages that are available to them 2. I changed the logic to validate the DICE CWT chain since [it needs at least 2 certificates](https://android.googlesource.com/platform/tools/security/+/d80118316fb3b87092d4128196884b11fa19e08c/remote_provisioning/hwtrust/src/cbor/dice/chain.rs#109). This has a side effect that the generated UDS certificate will not be checked for valid form since it is not parsed [earlier](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/host/provisioning/ft_lib/src/lib.rs#L416-L418) as well Tested by running `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_cwt_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test` `//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test`, and `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_tpm_cw340_test` targets locally
…iate locations The [documentation](https://github.com/lowRISC/opentitan/blob/9d35c96fc0728d82fcc0a0e1ffa06ab532dbe448/sw/device/silicon_creator/lib/drivers/keymgr.h#L111-L134) for keymgr functions mention that call to `sc_keymgr_sw_binding_unlock_wait` is recommended after calls to `sc_keymgr_sw_binding_set` or `sc_keymgr_advance_state`. This commit adds calls to `sc_keymgr_sw_binding_unlock_wait` at appropriate locations in `sw/device/silicon_creator/manuf/base/ft_personalize.c` as per that documentation Tested by running `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`, and `//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test` targets locally Signed-off-by: Lovepreet Singh <lpsingh@google.com>
… it is This commit changes the behavior of the provisioning flow so that the firmware sends generated UDS CWT DICE certificate to the host, and then expects the host to send it back. This allows for saving space in SRAM by using only one perso blob variable (done in a later commit as a mechanical refactor of code). Tested by running `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_cwt_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test`, and `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_tpm_cw340_test` targets locally Signed-off-by: Lovepreet Singh <lpsingh@google.com>
…ve at time
The device no longer needs to use the perso blob it sent to the host
after changes in previous commit where the host sends back UDS CWT
certificate. Therefore, only one of those variables need to be live at a
given time: `blob_to_host` during pre-endorsement stage and
`blob_from_host` during post-endorsement stage.
This commit does a mechanical refactor to split the perso blob variables
into appropriate union fields so that device SRAM usage can be reduced.
`blob_from_host` is moved to shared post-endorsement since it is used in
stage 1 and after stage 2.
I also deleted variable to keep track of UDS CWT certificate offset in
blob_to_host since it is not needed anymore.
Tested by running
`//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_cwt_cw340_test`,
`//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`,
`//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test`,
and `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_tpm_cw340_test`
targets locally
Output from `bloaty` for `.bss` section in
`ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf`
before this change:
```
0.0% 0 17.7% 27.4Ki .bss
NAN% 0 75.5% 20.7Ki provision.perso_data
NAN% 0 14.6% 4.00Ki owner_page
NAN% 0 7.2% 1.97Ki main_spi_buf
NAN% 0 1.0% 272 ottf_console_spi_getc.info
NAN% 0 0.4% 100 pxReadyTasksLists
NAN% 0 0.2% 52 main_console
NAN% 0 0.1% 40 status_report_list
NAN% 0 0.1% 24 rand_testutils_rng_ctx
NAN% 0 0.1% 20 xDelayedTaskList1
```
Output from `bloaty` for `.bss` section in
`ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf`
after this change:
```
0.0% 0 14.9% 22.4Ki .bss
NAN% 0 70.0% 15.7Ki provision.perso_data
NAN% 0 17.8% 4.00Ki owner_page
NAN% 0 8.8% 1.97Ki main_spi_buf
NAN% 0 1.2% 272 ottf_console_spi_getc.info
NAN% 0 0.4% 100 pxReadyTasksLists
NAN% 0 0.2% 52 main_console
NAN% 0 0.2% 40 status_report_list
```
Currently, the pre-endorsement stage uses `all_certs` to store TBS certificates before pushing them into perso blob sent to the host. This commit makes a mechanical change in code to use a separate smaller scratch certificate buffer during the pre-endorsement stage.`all_certs` is now needed only in sub-stage 1 of the post-endorsement stage. This does not change the amount of SRAM needed. The motive behind this change is to be able to reason about appropriate size of `all_certs` keeping in mind that it is only needed during sub-stage 1 of the post-endorsement stage. Tested by running `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_cwt_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test`, and `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_tpm_cw340_test` targets locally Signed-off-by: Lovepreet Singh <lpsingh@google.com>
Currently, the post endorsement stage uses a large `all_certs` buffer to store all the certificates received from the host. Then the firmware writes the certificates from that buffer into internal flash. Gemini suggested that this behavior can be changed so that the firmware writes certificate data to the internal flash directly from the perso blob from host. This commit replaces `all_certs` buffer with a smaller scratch `cert_buffer` as precursor to the suggested change 1. Instead of storing all certificates read from `blob_from_host`, the code now reads each one of them into `cert_buffer` (overwriting the previously read certificate each time). This logic is still preserved so as to find any issues with reading certificates from `blob_from_host` before writing anything to the internal flash. 2. The code then re-reads each certificate from `blob_from_host` into `cert_buffer` to write them to the internal flash as per the layout Step 1 can be optimized further but I haven't done so in this commit to keep the set of changes small. I will optimize that in the next commit (part 2) Tested by running `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_tpm_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_cwt_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`, and `//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test` targets locally Output from `bloaty` for `.bss` section in `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` before this change: ``` 0.0% 0 14.9% 22.4Ki .bss NAN% 0 70.0% 15.7Ki provision.perso_data NAN% 0 17.8% 4.00Ki owner_page NAN% 0 8.8% 1.97Ki main_spi_buf NAN% 0 1.2% 272 ottf_console_spi_getc.info NAN% 0 0.4% 100 pxReadyTasksLists NAN% 0 0.2% 52 main_console NAN% 0 0.2% 40 status_report_list NAN% 0 0.1% 24 rand_testutils_rng_ctx NAN% 0 0.1% 20 xDelayedTaskList1 NAN% 0 0.1% 20 xDelayedTaskList2 ``` Output from `bloaty` for `.bss` section in `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 10.8% 15.4Ki .bss NAN% 0 56.4% 8.71Ki provision.perso_data NAN% 0 25.9% 4.00Ki owner_page NAN% 0 12.8% 1.97Ki main_spi_buf NAN% 0 1.7% 272 ottf_console_spi_getc.info NAN% 0 0.6% 100 pxReadyTasksLists NAN% 0 0.3% 52 main_console NAN% 0 0.3% 40 status_report_list NAN% 0 0.2% 24 rand_testutils_rng_ctx NAN% 0 0.1% 20 xDelayedTaskList1 ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
xorptr
force-pushed
the
perso_ft_provisioning_reduce_sram_usage_remove_all_certs_buffer
branch
from
August 21, 2026 00:35
0da5909 to
86f245a
Compare
…rtificates to internal flash In the previous commit, a small scratch cert buffer is used to read endorsed certificates sent by the host in perso blob before writing them to the internal flash. This commit is part 2 of the changes suggested by Gemini to directly use perso blob from the host to write endorsed certificates to the internal flash. This commit changes the code to populate `perso_tlv_cert_obj_view_t` directly from the perso blob object sent from the host to do preliminary checks. The same idea is then used to write the endorsed certificates to the internal flash. This eliminates the need for the scratch cert buffer for the purpose of writing endorsed certificates to the internal flash, hence that buffer is now removed leaving more space in `.bss` section Tested by running ` //sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_cwt_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`, `//sw/host/provisioning/orchestrator/tests:e2e_emulation_cw340_test`, and `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_tpm_cw340_test` targets locally Output from `bloaty` for `.bss` section in `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` before this change: ``` 0.0% 0 10.8% 15.4Ki .bss NAN% 0 56.4% 8.71Ki provision.perso_data NAN% 0 25.9% 4.00Ki owner_page NAN% 0 12.8% 1.97Ki main_spi_buf NAN% 0 1.7% 272 ottf_console_spi_getc.info NAN% 0 0.6% 100 pxReadyTasksLists NAN% 0 0.3% 52 main_console NAN% 0 0.3% 40 status_report_list NAN% 0 0.2% 24 rand_testutils_rng_ctx NAN% 0 0.1% 20 xDelayedTaskList1 NAN% 0 0.1% 20 xDelayedTaskList2 NAN% 0 0.1% 20 xPendingReadyList NAN% 0 0.1% 20 xSuspendedTaskList ``` Output from `bloaty` for `.bss` section in `ft_personalize_emulation_dice_mldsa_sim_qemu_rom_with_fake_keys.elf` after this change: ``` 0.0% 0 10.2% 14.4Ki .bss NAN% 0 53.4% 7.71Ki provision.perso_data NAN% 0 27.7% 4.00Ki owner_page NAN% 0 13.7% 1.97Ki main_spi_buf NAN% 0 1.8% 272 ottf_console_spi_getc.info NAN% 0 0.7% 100 pxReadyTasksLists NAN% 0 0.4% 52 main_console NAN% 0 0.3% 40 status_report_list NAN% 0 0.2% 24 rand_testutils_rng_ctx NAN% 0 0.1% 20 xDelayedTaskList1 NAN% 0 0.1% 20 xDelayedTaskList2 ``` Signed-off-by: Lovepreet Singh <lpsingh@google.com>
Change buffer size for scratch buffer used to generate TBS certificates to max of 1024 (current size) or max UDS TBS certificate size from template For hashing endorsed certificates, the size is kept same as now since the buffer will only be used to hash non-PQ certs and SKU extension certs, both of which are currently generated by the firmware Signed-off-by: Lovepreet Singh <lpsingh@google.com>
xorptr
force-pushed
the
perso_ft_provisioning_reduce_sram_usage_remove_all_certs_buffer
branch
from
August 21, 2026 00:37
86f245a to
754fc72
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR removes
all_certsbuffer used during provisioning in perso firmware to save ~8KiB in.bsssection in SRAMThis PR consists of a series of commits with small changes to achieve the goal:
all_certsis used during pre-endorsement stage to build TBS certificates, and post-endorsement stages to write certificates to the internal flash. This commit movesall_certsto union variable for post-endorsement stage while adding a new smaller buffer for the pre-endorsement stage. This allows optimizingall_certsbased on what it is used for during post-endorsement stageall_certswith a smaller scratch buffer to read endorsed certificates into when writing to internal flashThis changes
.bsssection size from22.4Kito14.4Ki. See individual commits for more detailsChanges are based on PR #31036