lowRISC / opentitan

OpenTitan: Open source silicon root of trust
https://www.opentitan.org
Apache License 2.0
2.59k stars 782 forks source link

[manuf] DICE: The certificates generated by perso_extension are inaccessible in baseline perso_fw due to design restrictions #24943

Open tommychiu-github opened 1 month ago

tommychiu-github commented 1 month ago

Test point name

NA

Host side component

None

OpenTitanTool infrastructure implemented

None

Silicon Validation (SiVal)

Yes

Emulation Targets

Contact person

No response

Checklist

Please fill out this checklist as items are completed. Link to PRs and issues as appropriate.

Some DICE endorsement and storing mechanisms are not feasible for DICE-CWT.

  1. In the baseline perso_fw, when generating a DICE chain by "personalize_gen_dice_certificates()", it expects the UDS is "need to be endorsed" by the host. (link)
  2. In the baseline perso_fw, only a certificate which is endorsed by the host will be send back to device via perso_blob_to_host. (link)

As to the Android-profile of DICE, 2 format of certificate chain are required.

  1. ChipFoundryRoot -> ChipFoundrySub -> UDS (X.509)
  2. UDS -> CDI_0 -> CDI_1 -> ... (CWT-CBOR)
    • This chain is generated on device without any help from the host, and the CBOR-UDS is no need to be signed.

So for DICE-CWT implementation, we'll utilize the baseline persofw to generate the X.509-UDSCert and the rests CBOR-CDI*. The per-sku extension will be used to generate the CBOR-UDS.

However due to the restrictions described above the CBOR-UDS cannot be parsed since it's not sending back to device from the host. One possible solution is to add a global flag to indicate this extra certificate, to make the digest complete. Ref: https://github.com/lowRISC/opentitan/commit/2d0430a921e92c138bbd056111a3c5c15670a8b8

tommychiu-github commented 1 month ago

@timothytrippel for comment.

timothytrippel commented 4 weeks ago

Currently, the FT personalization flow only generates all three DICE certs in X.509 format using the DiceTcbInfo extension specified by the TCG. We have called this certificate format the "TCG Profile" in the OpenTitan DICE Certificates RFC document. In this profile's implementation, the CDI_0 and CDI_1 certs are both endorsed on device, except the UDS cert is streamed off device for endorsement on the host (as you point out, and is shown in the code here where the needs_endorsement parameter of the perso_tlv_prepare_cert_for_shipping() function is set to true).

However this is only how the current base perso FW works for X.509 TCG Profile DICE certs. When you implement the CWT Android profile, as also described in the the OpenTitan DICE Certificates RFC document, we can simply update the base perso firmware to not set the needs_endorsement parameter of the perso_tlv_prepare_cert_for_shipping() function when sending out the UDS CWT cert from the device. Essentially we can have an "if-else" clause where we check if the DICE cert format is X.509 or CWT and if the latter, we don't mark UDS as needing endorsement.

The other chain (ChipFoundryRoot -> ChipFoundrySub -> UDS (X.509)) can then be generated by the perso extension (though we will have to stash the UDS pubkey in RAM during the initial DICE CWT cert chain building).

So to recap:

  1. we complete the implementation of the CWT cert codegen, creating two dice.c and dice_cwt.c libs
  2. update the base perso FW to detect the DICE cert gen lib compiled in (via a #define compile flag? or just by analyzing the first couple bytes of the cert blob itself?) and decide whether or not to mark the UDS cert as "needing endorsement",
  3. implement the second cert chain generation (ChipFoundryRoot -> ChipFoundrySub -> UDS (X.509)) in your SKU's perso extension

Will that work for you? We can discuss more offline tomorrow as well.

tommychiu-github commented 4 weeks ago

Currently, the FT personalization flow only generates all three DICE certs in X.509 format using the DiceTcbInfo extension specified by the TCG. We have called this certificate format the "TCG Profile" in the OpenTitan DICE Certificates RFC document. In this profile's implementation, the CDI_0 and CDI_1 certs are both endorsed on device, except the UDS cert is streamed off device for endorsement on the host (as you point out, and is shown in the code here where the needs_endorsement parameter of the perso_tlv_prepare_cert_for_shipping() function is set to true).

However this is only how the current base perso FW works for X.509 TCG Profile DICE certs. When you implement the CWT Android profile, as also described in the the OpenTitan DICE Certificates RFC document, we can simply update the base perso firmware to not set the needs_endorsement parameter of the perso_tlv_prepare_cert_for_shipping() function when sending out the UDS CWT cert from the device. Essentially we can have an "if-else" clause where we check if the DICE cert format is X.509 or CWT and if the latter, we don't mark UDS as needing endorsement.

The other chain (ChipFoundryRoot -> ChipFoundrySub -> UDS (X.509)) can then be generated by the perso extension (though we will have to stash the UDS pubkey in RAM during the initial DICE CWT cert chain building).

So to recap:

  1. we complete the implementation of the CWT cert codegen, creating two dice.c and dice_cwt.c libs
  2. update the base perso FW to detect the DICE cert gen lib compiled in (via a #define compile flag? or just by analyzing the first couple bytes of the cert blob itself?) and decide whether or not to mark the UDS cert as "needing endorsement",
  3. implement the second cert chain generation (ChipFoundryRoot -> ChipFoundrySub -> UDS (X.509)) in your SKU's perso extension

Will that work for you? We can discuss more offline tomorrow as well.

Yes, this approach makes sense to me as well. I can update a patch for item#2 later. Thanks for the discussion.