| @@ -1,8 +1,8 @@ |
| 1 | 1 | <div style="font-size: 0.85em; color: #656d76; margin-bottom: 1em; padding: 0.5em; background: #f6f8fa; border-radius: 4px;"> |
| 2 | | -📄 Source: <a href="https://github.com/chipsalliance/caliptra-sw/blob/c43041a0e8e8cf14a742f87117cbc02fb917a499/fmc/README.md" target="_blank">chipsalliance/caliptra-sw/fmc/README.md</a> @ <code>c43041a</code> |
| 2 | +📄 Source: <a href="https://github.com/chipsalliance/caliptra-sw/blob/af5f9cf200595ef01b3c00569625b59a9e915da7/fmc/README.md" target="_blank">chipsalliance/caliptra-sw/fmc/README.md</a> @ <code>af5f9cf</code> |
| 3 | 3 | </div> |
| 4 | 4 | |
| 5 | | -# Caliptra - FMC Specification v2.0.1 |
| 5 | +# Caliptra - FMC Specification v2.1 |
| 6 | 6 | |
| 7 | 7 | *Spec Version: 0.9* |
| 8 | 8 | |
| @@ -327,14 +327,36 @@ |
| 327 | 327 | |
| 328 | 328 | ## PCR registers |
| 329 | 329 | |
| 330 | | -FMC has the responsibility to update 2 PCR registers.<br> |
| 331 | | -FMC updates PCR3 to reflect the firmware update Journey with measurements of RT firmware and FW Manifest. This register is only cleared on cold reset.<br> |
| 332 | | -FMC updates PCR2 to reflect only the Current running firmware with measurements of RT firmware and FW Manifest. This register is cleared on all reset types.<br> |
| 333 | | -FMC locks its PCR registers before handing control to RT firmware so that they may not be cleared later in the boot. |
| 330 | +FMC maintains PCR2 (Runtime current) and PCR3 (Runtime journey) using the Runtime |
| 331 | +TCI supplied by ROM. It does not separately hash or extend the firmware manifest |
| 332 | +into these PCRs. |
| 333 | + |
| 334 | +An extension computes `SHA384(previous PCR value || Runtime TCI)`. PCR2 represents |
| 335 | +the current Runtime measurement; PCR3 accumulates Runtime measurement changes |
| 336 | +since cold reset. Both PCR values start at zero on cold reset. |
| 337 | + |
| 338 | +| Reset path | PCR2 (current) | PCR3 (journey) | FMC PCR-log action | |
| 339 | +| ---------- | -------------- | -------------- | ------------------ | |
| 340 | +| Cold reset | Clear, then extend with Runtime TCI | Extend with Runtime TCI | Append one `RtTci` entry for PCR2 and PCR3 | |
| 341 | +| Update reset, predicted PCR2 differs from the stored value | Clear, then extend with Runtime TCI | Extend the retained value with Runtime TCI | Append one `RtTci` entry for PCR2 and PCR3 | |
| 342 | +| Update reset, predicted PCR2 matches the stored value | Leave unchanged | Leave unchanged | Do not append an entry | |
| 343 | +| Warm reset | Leave unchanged | Leave unchanged | Do not append an entry | |
| 344 | + |
| 345 | + |
| 346 | +FMC locks both PCRs after this reset-specific processing and before handing |
| 347 | +control to Runtime. Resetting the PCR locks does not itself erase the PCR values. |
| 334 | 348 | |
| 335 | 349 | ## FMC boot flow |
| 336 | 350 | |
| 337 | 351 | The following list of steps are to be performed by FMC on each boot when ROM jumps to its entry point. Any failures are considered fatal. |
| 352 | + |
| 353 | +If the FHT fails validation, FMC calls the shared fatal-error handler with |
| 354 | +`FMC_HANDOFF_INVALID_FHT`. The handler clears the crypto engines, erases unlocked |
| 355 | +Key Vault slots, locks the SHA accelerator, stops watchdog timer 1, and reports |
| 356 | +the error in both firmware error registers. It then loops, aborting pending |
| 357 | +SoC-to-Caliptra mailbox transactions. FMC does not run its DICE flow or transfer |
| 358 | +control to Runtime. Key Vault cleanup skips slots with a write lock or use lock; |
| 359 | +it does not guarantee erasure of every key. |
| 338 | 360 | |
| 339 | 361 | 1. FMC locates the Firmware Handoff Table (FHT) responsible for passing vital configuration and other data from one firmware layer to the next. This is found |
| 340 | 362 | at well-known address CALIPTRA_FHT_ADDR. |
| @@ -343,12 +365,9 @@ |
| 343 | 365 | utilizes the ROM-based FIPS Crypto Module or its own internal FIPS Crypto services in implementations without a discrete FW-based FIPS Crypto Module. |
| 344 | 366 | 1. FMC locates the Manifest at fht.manifest_load_addr. |
| 345 | 367 | 1. FMC reads the measurement of the Runtime FW Module, TCI<sub>RT</sub>, from the DCCM datavault that has previously been validated by ROM. |
| 346 | | -1. FMC reads the manifest address of the Image Bundle from the HandOff Table, and calculates the SHA-384 TCI<sub>MAN</sub> |
| 347 | | -1. FMC clears Current PCR |
| 348 | | -1. FMC extends Current and Journey PCR registers with TCI<sub>RT</sub>. |
| 349 | | -1. FMC extends Current and Journey PCR registers with TCI<sub>MAN</sub>. |
| 368 | +1. FMC applies the reset-specific PCR handling described above. When an extension is needed, it clears Current PCR, extends Current and Journey PCRs with TCI<sub>RT</sub>, and appends one `RtTci` log entry. |
| 350 | 369 | 1. FMC locks Current and Journey PCR registers. |
| 351 | | -1. FMC derives CDI<sub>RT</sub> from CDI<sub>FMC</sub> mixed with TCI<sub>RT</sub> and TCI<sub>MAN</sub>, then stores it in the Key Vault. |
| 370 | +1. FMC derives CDI<sub>RT</sub> using the HMAC-SHA-512 KDF with CDI<sub>FMC</sub> as the key, `alias_rt_cdi` as the label, and TCI<sub>RT</sub> as the context. It stores CDI<sub>RT</sub> in a separate Key Vault slot; the derivation does not include a separate manifest digest or overwrite CDI<sub>FMC</sub>. |
| 352 | 371 | 1. FMC updates fht.rt_cdi_ecdsa_kv_hdl and fht.rt_cdi_mldsa_kv_hdl in the FHT. |
| 353 | 372 | 1. FMC derives ECDSA and MLDSA AliasKeyPair<sub>RT</sub> from CDI<sub>RT</sub>. The ECDSA Private Key and the MLDSA Key Generation Seed are stored in the Key Vault, while the ECDSA Public Key X and Y coordinates and MLDSA Public Key are stored in the DCCM datavault. |
| 354 | 373 | 1. FMC updates fht.rt_priv_key_ecdsa_kv_hdl, fht.rt_pub_key_ecdsa_x_dv_hdl, and fht.rt_pub_key_ecdsa_y_dv_hdl in the FHT. |
| @@ -418,12 +437,16 @@ |
| 418 | 437 | |
| 419 | 438 | rect rgba(0, 100, 200, .2) |
| 420 | 439 | |
| 440 | + opt Cold reset or update reset with a different predicted PCR2 |
| 421 | 441 | FMC->>+FIPS: ClearPcr(RtCurrent) |
| 422 | 442 | FIPS-->>-FMC: return() |
| 423 | 443 | FMC->>+FIPS: ExtendPcr(RtCurrent, PCR_hdl_RT, RtTci) |
| 424 | 444 | FIPS-->>-FMC: return() |
| 425 | 445 | FMC->>+FIPS: ExtendPcr(RtJourney, PCR_hdl_RT, RtTci) |
| 426 | 446 | FIPS-->>-FMC: return() |
| 447 | + FMC->>FMC: Append RtTci to PCR log for PCR2 and PCR3 |
| 448 | + end |
| 449 | + |
| 427 | 450 | FMC->>+FIPS: LockPcr(RtCurrent) |
| 428 | 451 | FIPS-->>-FMC: return() |
| 429 | 452 | FMC->>+FIPS: LockPcr(RtJourney) |
| @@ -498,13 +521,18 @@ |
| 498 | 521 | |
| 499 | 522 | ## Resets |
| 500 | 523 | |
| 501 | | -FMC does not distinguish between cold boots or any other type of reset. Instead, FMC is designed such that it always performs the same set of operations |
| 502 | | -regardless of which reset path caused it to be executed. |
| 524 | +FMC distinguishes cold, warm, and update resets. Its PCR handling follows the |
| 525 | +table in [PCR registers](#pcr-registers): warm resets preserve PCR2 and PCR3, |
| 526 | +while update resets extend them only when the predicted PCR2 differs from the |
| 527 | +retained value. FMC rejects an unknown reset reason with `FMC_UNKNOWN_RESET`. |
| 503 | 528 | |
| 504 | 529 | ## Update and recovery |
| 505 | 530 | |
| 506 | | -FMC does not participate in Caliptra update/recovery flows. FMC is designed such that it does not perform any different steps during update |
| 507 | | -and simply behaves the same as it does during other cold/warm resets. |
| 531 | +ROM handles firmware authentication and loading during an update. After ROM |
| 532 | +transfers control to FMC, FMC uses the Runtime TCI in the Data Vault to decide |
| 533 | +whether to update PCR2, PCR3, and the PCR log. It then derives the Runtime Alias |
| 534 | +identity and prepares the handoff to Runtime. FMC does not independently load |
| 535 | +or authenticate the update image. |
| 508 | 536 | |
| 509 | 537 | ## Fake FMC |
| 510 | 538 | |