Skip to content

[ujson,perso] Support optional fields in ManufCertgenInputs json data to device - #31202

Open
xorptr wants to merge 1 commit into
lowRISC:earlgrey_1.0.0from
xorptr:optional_manuf_certgen_fields
Open

xorptr wants to merge 1 commit into
lowRISC:earlgrey_1.0.0from
xorptr:optional_manuf_certgen_fields

Conversation

@xorptr

@xorptr xorptr commented Sep 1, 2026

Copy link
Copy Markdown

This PR makes changes to address the issue pointed out by @sasdf in #31051 (comment)

This PR addresses that issue by adding support to declare optional fields in structs that are serialized and deserialized by ujson. With this new support the new perso tool will not send newly added fields (to support ML-DSA provisioning) to older perso firmware binaries, thereby addressing the issue mentioned above

The changes add new macros where few of the fields can be optional.The macros are expanded to declare structs, and declare functions for serialization and deserialization during compilation. I have added few unit tests to check that structs with optional fields produce expected JSON data.

Comment thread sw/device/lib/ujson/ujson_derive.h Outdated
@xorptr
xorptr force-pushed the optional_manuf_certgen_fields branch 2 times, most recently from b0bfbe4 to f099aad Compare September 14, 2026 02:50
@xorptr
xorptr marked this pull request as ready for review September 14, 2026 02:55
@xorptr
xorptr requested review from a team as code owners September 14, 2026 02:55
@xorptr
xorptr requested review from cfrantz, jwnrt, moidx and sasdf and removed request for a team September 14, 2026 02:55
@sasdf sasdf added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026

@sasdf sasdf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. I feel we have some code duplication between normal and optional fields in ujson_derive.h, but we can refactor them in other PRs later.

@sasdf sasdf added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
Perso changes to support ML-DSA certificates during provisioning
recently added new fields in [`ManufCertgenInputs`](https://github.com/lowRISC/opentitan/blob/2a28b8761d771a889056b4b02d991acd6a6a4082/sw/device/lib/testing/json/provisioning_data.h#L140-L142).
This breaks the compatibility between the new perso tool running on the
host and older perso firmware binaries. The new tool sends these
additional fields in JSON data to the older binaries, and older firmware
binaries [fail to
deserialize](https://github.com/lowRISC/opentitan/blob/2a28b8761d771a889056b4b02d991acd6a6a4082/sw/device/lib/ujson/ujson_derive.h#L235)
the JSON data for `ManufCertgenInputs`. This caused CI tests to fail in
downstream SKU specific repositories.

This commit declares new ujson macros to support declaring optional
fields (but not strings).

- When expanding to declarations in C, the macro will create 2 struct
  members for each optional field: one denoting whether the optional
  field is present or not, and the other denoting data in the optional
  field which is valid only if it is present. For Rust, the macro,
  expansion creates a single member with type `Option<_>` and marks it
  with `serde` attribute to skip serializing that field if it is `None`

- When serializing an optional field, C code will skip putting out JSON
  string for the field if it is marked as not present using respective
  struct member. Rust code uses the `serde` attribute mentioned above to
  skip putting out JSON for that field if it is set to `None`

    - The code computes the number of fields that will be put out during
      serialization so that it can decide whether or not to put `,` at
      end of the field data. This logic used to store number of fields
      declared in the struct (determined at compile time). With optional
      fields, this is changed to determine the number of such fields
      based on struct members that indicate whether the optional field
      is present or not

- When deserializing an optional field, C code will initialize the
  struct members to assume that the field is not present. If the field
  is found to be present while parsing JSON string, the code will mark
  the struct member to indicate so and copy the field data in respective
  struct member. For Rust code, I am relying on `serde` to take the
  appropriate action when deserializing JSON data

- The expansion for declarations, serialization, and deserialization of
  non-optional fields is not changed

I also removed the field `generate_mldsa_uds_cert` from
`ManufCertgenInputs` since the struct member that indicates whether
`dice_mldsa_auth_key_key_id` is present or not now does the job for that
field, i.e. ML-DSA certificate support is enabled depending on whether
the optional field `dice_mldsa_auth_key_key_id` is present or not.

With the changes mentioned above, the new host tool does not send newly
added fields in JSON data to older perso firmware binaries and this
avoids failures in tests that do this

I also added various tests to check various cases with optional fields
in general, and also with `ManufCertgenInputs` in particular.

Tested by running the following targets locally:

- `//sw/device/lib/testing/json:provisioning_data_test`
- `//sw/host/provisioning/ujson_lib:ujson_lib_test`
- `//sw/device/lib/ujson:example_test`
- `//sw/device/lib/ujson/rust:roundtrip_test`
- `//sw/host/provisioning/orchestrator/tests:e2e_emulation_dice_mldsa_cw340_test`
  with bazel arg `--//sw/host/provisioning/cert_lib:enable_mldsa_signing_for_test`
- `//sw/host/provisioning/orchestrator/tests:e2e_multistage_emulation_dice_mldsa_cw340_test`
  with bazel arg `--//sw/host/provisioning/cert_lib:enable_mldsa_signing_for_test`

Signed-off-by: Lovepreet Singh <lpsingh@google.com>
@xorptr

xorptr commented Sep 14, 2026

Copy link
Copy Markdown
Author

Rebased on top of latest commit in earlgrey_1.0.0: 2dfededbe24bd1551164c251b304d8aff888cc44

@xorptr xorptr changed the title [WIP] Optional manuf certgen inputs fields Optional fields in ManufCertgenInputs json data to device Sep 14, 2026
@xorptr xorptr changed the title Optional fields in ManufCertgenInputs json data to device [ujson,perso] Support optional fields in ManufCertgenInputs json data to device Sep 14, 2026
@xorptr

xorptr commented Sep 14, 2026

Copy link
Copy Markdown
Author

LGTM. I feel we have some code duplication between normal and optional fields in ujson_derive.h, but we can refactor them in other PRs later.

Yes. There are too many places in code where I needed to make change for adding 3rd argument to macros defining structs with UJSON_SERDE_STRUCT. So I created new macros to avoid those changes in this PR. That can be done as a cleanup in follow up PRs

@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 14, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@xorptr xorptr added the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Sep 15, 2026
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.

3 participants