-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Platform Descriptor Store (PDS) for Extensible IFWI Metadata
The Platform Descriptor Store (PDS) is an extensible, self-describing binary region within the Caliptra flash layout that stores platform-level data as a linked list of UUID-typed descriptors with variable-size payloads. It enables vendors to embed non-firmware data in the IFWI without modifying the flash layout specification.
Scope
The following parts of the caliptra-mcu-sw project will be affected:
New crate:
common/pds/-- ano_stdparser crate for reading the PDS binary format. Provides iterator-based traversal of the descriptor chain with CRC-32 header validation. No heap allocation.
Modified files:
common/flash-image/src/lib.rs-- new constantPLATFORM_DESCRIPTOR_STORE_IDENTIFIER = 0x00000003builder/src/flash_image.rs----pdsCLI flag to include a PDS binary in the generated flash imagedocs/src/flash_layout.md-- updated to document the PDS as a standard image with its own
Image Information entrydocs/src/platform_descriptor_store.md-- new specification page describing the binary format
No changes to:
- Caliptra firmware (PDS uses the existing
authorize_and_stashverification flow without any code changes) - SoC Manifest format (PDS is verified via a standard Image Metadata Entry with Component Id
0x00000003) - Flash layout header format or partition table
No impact to Trademark Compliance. PDS is an optional, additive feature within the existing flash layout framework. It does not introduce new mandatory requirements for Caliptra Certification. Platforms that do not use PDS simply omit the Image Information entry.
Rationale
The current Caliptra flash layout supports firmware images (Caliptra FMC+RT, SoC Manifest, MCU Runtime, SoC images) but has no mechanism for storing non-firmware platform data. When programs need to embed additional data -- such as device identity binding, build provenance, platform compatibility information, or configuration attributes -- there is no standard way to do so without either repurposing an existing image slot or changing the flash layout specification.
This creates a recurring problem: late-in-the-program asks that require storing new data in flash force ad-hoc solutions that are program-specific and not reusable across Caliptra-based platforms.
The PDS solves this by providing a single, generic container with the following properties:
- Extensible without layout changes. Adding new data only requires defining a UUID and appending a descriptor. No flash offsets, headers, or image counts change.
- Backwards compatible. At the IFWI level: firmware that does not know about PDS skips the Image Information entry with Identifier
0x00000003(unrecognized Identifiers are ignored). Firmware that expects PDS but does not find it handles the absence gracefully. At the descriptor level: firmware that does not recognize a descriptor UUID simply skips it. The container format (header + linked list) never changes. - Verified by Caliptra. The PDS hash is stored in a standard Image Metadata Entry in the SoC Manifest. Caliptra RT verifies it via the existing
authorize_and_stashflow with no code changes to Caliptra firmware. - Build-time only. The PDS is written during IFWI generation and is read-only at runtime. Changes require re-signing the SoC Manifest.
- Vendor-neutral. Descriptor types are identified by RFC 4122 UUIDs. Any vendor can define descriptors without coordination. The PDS format itself contains no vendor-specific fields.
Why not use existing image slots?
Firmware images are opaque binaries verified by hash. They have no internal structure that supports extensibility or self-description. Encoding multiple data items into a single firmware image would require a custom format per program, defeating the purpose of a standard layout.
Why not extend the SoC Manifest?
The SoC Manifest has a fixed structure (preamble + Image Metadata Collection) designed for firmware verification. Adding arbitrary vendor data to the manifest would conflate verification metadata with platform data and would be less extensible, since adding new data types would require manifest format coordination rather than simply defining a new UUID.
Prior Art
Several existing formats address related problems in firmware metadata storage. PDS was designed with awareness of these, but fills a gap that none of them cover for the Caliptra IFWI context:
| Format | Similarity to PDS | Why it does not fit |
|---|---|---|
| SMBIOS (DMTF DSP0134) | Typed data structures in firmware for system management info (type ID + variable-length records) | Fixed type IDs (0-255) controlled by DMTF registry. Not UUID-based, not vendor-extensible without DMTF coordination. Designed for OS-visible hardware inventory, not IFWI metadata. |
| UEFI Variables | GUID-namespaced key/value pairs, extensible by any vendor | Runtime read/write (not build-time only). Stored in NVRAM, not in SPI flash images. Requires UEFI firmware infrastructure, which Caliptra-based platforms do not use. |
| UEFI Firmware Volumes (FV) | GUID-identified firmware files within a firmware volume | Part of the UEFI PI specification. Requires UEFI firmware infrastructure. Much more complex than needed for non-firmware metadata. |
| Devicetree (FDT) | Extensible hardware description data structure passed to OS at boot | Tree structure, not a simple linked list. Designed for hardware description, not vendor metadata in SPI flash images. Typically used on ARM/RISC-V for OS hardware discovery. |
| coreboot CBFS | Container format for firmware components within a coreboot ROM | Specific to the coreboot ecosystem. File-based, not descriptor-based. |
PDS fills the gap of a simple, UUID-extensible, build-time-only, linked-list container for non-firmware metadata within an SPI flash image, verified through the existing Caliptra chain of trust.
Binary Format
PDS Header (148 bytes)
| Field | Size | Description |
|---|---|---|
| magic | 4B | Must be 0x50445331 |
| header_size | 4B | Size of this header (currently 148 bytes) |
| header_crc | 4B | CRC-32 over bytes from offset 12 to header_size |
| version | 4B | Header format version (currently 1) |
| first_descriptor_offset | 4B | Byte offset from PDS start to first descriptor, or 0 |
| pds_version_string | 128B | Null-terminated UTF-8 version string |
PDS Descriptor Header (32 bytes)
| Field | Size | Description |
|---|---|---|
| header_size | 4B | Size of this descriptor header (currently 32 bytes) |
| payload_offset | 4B | Byte offset from PDS start to payload data |
| payload_size | 4B | Size of payload in bytes |
| next_descriptor_offset | 4B | Byte offset from PDS start to next descriptor, or 0 |
| descriptor_type | 16B | UUID (RFC 4122) identifying the descriptor type |
Descriptor type UUIDs and payload formats are vendor-defined. The PDS specification defines the container format only.
Alignment
- Descriptor headers must start at 4-byte aligned offsets
- Parsers must copy headers into local aligned structs before accessing fields (required for RISC-V and other architectures that do not support unaligned memory access)
Chain Rules
- Descriptors form a singly-linked list via
first_descriptor_offsetandnext_descriptor_offset - Each
next_descriptor_offsetmust point to a location strictly greater than the current descriptor's offset (forward-only, prevents loops) - The chain terminates when
next_descriptor_offsetis 0 - Duplicate UUIDs are permitted (first match wins for lookup, all matches iterable)
- Parsers must enforce a maximum descriptor count to bound traversal time (recommended default: 32)
- Parsers must validate that all offset fields (
first_descriptor_offset,next_descriptor_offset,payload_offset,payload_offset + payload_size) fall within[0, pds_size)before dereferencing. Out-of-bounds offsets must be treated as a parse error
Example Use Cases
The PDS container format is vendor-neutral. Vendors define their own descriptor type UUIDs and payload formats. The following are examples of how the PDS could be used:
IFWI Generation Tool Provenance
A descriptor could record information about the tool that generated the IFWI, aiding in debugging tool-related issues in the field:
| Field | Example Value |
|---|---|
| descriptor_type | {a1b2c3d4-e5f6-7890-abcd-ef0123456789} (vendor-defined UUID) |
| payload | Tool name, tool version, git commit hash, build timestamp |
If a customer reports a boot failure, the PDS can be inspected to determine exactly which tool version produced the IFWI, without relying on external tracking systems.
Silicon/SoC/Platform Identity Binding
A descriptor could bind the IFWI to a specific silicon instance, SoC revision, or platform variant, preventing an IFWI built for one platform from being loaded on another:
| Field | Example Value |
|---|---|
| descriptor_type | {f1e2d3c4-b5a6-9870-fedc-ba9876543210} (vendor-defined UUID) |
| payload | Platform identifier, SoC revision, silicon lot ID |
Firmware can read this descriptor at runtime and compare against hardware identity registers to reject mismatched IFWIs before proceeding with boot.
Other Potential Uses
- Impactless update version lists: Record which firmware versions can be applied without requiring a full slot switch
- Debug policy flags: Encode debug enable/disable policy per build variant
- Regulatory or compliance metadata: Embed certification identifiers or compliance markers alongside the firmware they apply to
In all cases, the PDS container format remains unchanged. Only the descriptor type UUID and payload format are vendor-defined.
Implementation Tradeoffs
Option A (chosen): PDS as a standard image within the existing flash layout
- PDS gets its own Identifier (
0x00000003), Image Information entry, and Image Metadata Entry - No changes to flash layout format, partition table, or Caliptra firmware
- Verified through the existing
authorize_and_stashflow - Simplest integration path
Option B (rejected): PDS as a new partition type outside the image framework
- Would require changes to the flash layout specification and partition table format
- Would need a new verification mechanism outside
authorize_and_stash - More disruptive with no clear benefit
Option C (rejected): Extend the SoC Manifest with vendor extension fields
- Conflates verification metadata with platform data
- Less extensible (adding new data types requires manifest format coordination rather than simply defining a new UUID)
Implementation Timeline
- Parser crate and flash image builder integration: implemented (PR #975 on caliptra-mcu-sw)
Test Plan
- Unit tests for PDS parser: valid header parsing, descriptor iteration, CRC-32 validation, empty PDS (no descriptors), UUID lookup, malformed header rejection, truncated binary handling
- Integration test: build flash image with PDS via
cargo xtask, verify PDS is present and parseable in the generated binary - Emulator test: boot with PDS-containing flash image, verify
authorize_and_stashsucceeds for PDS image
Maintenance
Naveen R. Iyer (iyernaveenr@gmail.com) is the author and will serve as the point of contact for the PDS feature. Bug fixes and enhancements will follow the standard fork-and-PR contribution process.