Skip to content
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

[ot_certs,rom_ext] optimize on-device certificate generation code-size #24558

Open
timothytrippel opened this issue Sep 11, 2024 · 1 comment
Labels
Manufacturing Issues related to manufacturing tasks (hw or sw) Priority:P2 Priority: medium SW:ROM_EXT ROM_EXT related issues Type:Enhancement Feature requests, enhancements

Comments

@timothytrippel
Copy link
Contributor

Description

Currently, there exists opentitantool support (opentitantool certificate codegen ...) for generating device libraries that may be used to generate X.509 certificate binary blobs. The libraries make use of a manually crafted device library that can encode simple ASN.1 structures. While this mechanism is extremely flexible, i.e., new certificate extensions can be easily crafted, it comes at a cost of code-size. Specifically, when analyzing the size-breakdown of various components in the ROM_EXT, we can see that:

  • the ASN.1 lib uses ~1.8kb
  • the X.509 CDI_0 certificate gen code uses ~2.35kb
  • the X.509 CDI_1 certificate gen code uses ~2.35kb
    for a grand total of ~6.5kb.

image

Moreover, we are currently attempting to add support for other DICE certificate extensions, and encodings (i.e., CBOR). If we continue to use the same approach, where we use host tools to generate device code that generates certificates on-device by calling into an additional CBOR device lib, then we could end up bloating the ROM_EXT (if we aim to provide a flexible ROM_EXT that can support multiple DICE certificate formats).

We should investigate a more efficient way to generate certificates on-device.

One approach could be to use an auto-generated fixed-size array template that various fields can be mem-copied into. The original rationale for not using such an approach was that doing so would require all fields in the TBS region to be fixed size, otherwise it is impossible to generate a fixed-sized template array. The biggest issue was that the serial number field in X.509 certs is encoded as an ASN.1 integer type, that does not allow 0 padding on the MSb side. One way around this is to just automatically set the MSb, since serial numbers are not crytpographic, rather just unique values (currently the serial number for OT certs is just a truncated SHA256 of the pub key). Other ideas/suggestions are also welcome.

Marking this lower priority for the time being, as I think we should investigate the size of the additional CBOR encoding libraries that are being vendored-in/implemented, and what room for code we have in ROM_EXT, and the impact the additional CBOR cert generation feature has on ROM_EXT code size before making a decision to pursue additional optimization work.

CC: @cfrantz

@timothytrippel timothytrippel added Priority:P2 Priority: medium Type:Enhancement Feature requests, enhancements SW:ROM_EXT ROM_EXT related issues Manufacturing Issues related to manufacturing tasks (hw or sw) labels Sep 11, 2024
@pamaury
Copy link
Contributor

pamaury commented Sep 12, 2024

Just a note here that if we really wanted to reduce the size, one possibility would be to hand-craft a function to produce a CDI certificate. This function could be flexible enough to handle both CDI by adding only the necessary parts at runtime. This would basically factor cdi_0_build_tbs and cdi_1_build_tbs into one function (and same for the cdi_0_build_cert). This might even potentially be done by the ot_certs library by allowing optional fields at runtime and having a single cdi.hsjon template.

The codegen code could also be smarter: there are parts of the certificate which are complexity fixed (ie never change at runtime). In this case, the codegen could simply put this into a constant byte array and memcpy instead of filling it at runtime.

If we further want to shave off a few bytes from the asn library, the integer pushing function is the obvious candidate: if we know that we always produce integer of fixed size (like you said, by setting the MSb) then we could simply memcpy the byte and save some bytes (since the function is quite "complex").

Yet another avenue is to look at the assembly code and see why the cdi_X_build_tbs functions are so large: maybe there are opportunities here to reduce the size by writing the code differently?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Manufacturing Issues related to manufacturing tasks (hw or sw) Priority:P2 Priority: medium SW:ROM_EXT ROM_EXT related issues Type:Enhancement Feature requests, enhancements
Projects
None yet
Development

No branches or pull requests

2 participants