Summary
I am integrating platform attestation with TPM as the Root of Trust on top of libspdm / spdm-emu and would like to understand the design intent behind the current TPM-backed measurement path.
Today, the TPM stub (spdm_device_secret_lib_tpm) appears to:
- Read PCR values via
Esys_PCR_Read and place digests into GET_MEASUREMENTS.measurement_record[] as DMTF measurement blocks (libspdm_fill_measurement_image_hash_block() in meas.c).
- Sign the SPDM MEASUREMENTS transcript with the responder storage key (
TPM_RESP_KEY) when SignatureRequested=1 (libspdm_generate_measurement_signature() → libspdm_responder_data_sign()).
- Leave
libspdm_measurement_opaque_data() as a placeholder (sequential bytes 0,1,2,...) with no TPM2_Quote, no IAK / attestation key, and no TPM2B_ATTEST in opaque_data.
Provisioning (setup-tpm.sh, keys.h) also defines only TPM_RESP_KEY / TPM_RESP_CERT_CHAIN (slot0), not a separate IAK for attestation.
Current vs expected behavior
What the code does today
| Step |
Implementation |
File |
| PCR read |
libspdm_tpm_read_pcr() → Esys_PCR_Read |
cryptlib_openssl/tpm/tpm.c |
| PCR in response |
DMTF blocks in measurement_record[] |
spdm_device_secret_lib_tpm/meas.c |
| MEASUREMENTS signature |
TPM_RESP_KEY signs SPDM L1/L2 transcript |
sign.c, libspdm_rsp_measurements.c |
| Opaque data |
Stub 0,1,2,...; no Quote |
meas.c → libspdm_measurement_opaque_data() |
| IAK / attestation key |
Not provisioned |
keys.h, setup-tpm.sh |
What I expected for TPM-rooted platform attestation
| Evidence |
Suggested SPDM carrier |
| PCR digests |
GET_MEASUREMENTS.measurement_record[] |
TPM2_Quote (TPM2B_ATTEST + TPMT_SIGNATURE) |
GET_MEASUREMENTS.opaque_data[] (e.g. OpaqueDataFmt1 + TCG element) |
| IAK certificate chain |
GET_CERTIFICATE slot1 (separate from device identity) |
| TCG Event Log (BIOS / IMA) |
GET_MEASUREMENT_EXTENSION_LOG.mel[] |
Quote qualifying data would bind to GET_MEASUREMENTS request nonce[32], not the response nonce.
Important distinction: MEASUREMENTS.signature covers the SPDM transcript (device identity). TPM Quote should not replace that field; it attests PCR state via the TPM attestation key (IAK).
Questions for maintainers
-
Was omitting TPM2_Quote intentional?
Is the current model (“PCR in measurement_record + device key signs SPDM transcript”) considered sufficient for “TPM-backed measurements” in libspdm’s scope?
-
Trust boundary
Without Quote, how should a verifier distinguish:
- PCR values read honestly from TPM, vs.
- PCR digests assembled by untrusted firmware/software and signed only by the SPDM device key?
-
SPDM field semantics
Should TPM Quote live in MEASUREMENTS.opaque_data (not in signature)?
Is there an upstream preference for SPDM_REGISTRY_ID_TCG + TPM2B_ATTEST || TPMT_SIGNATURE under OpaqueDataFmt1?
-
Key separation
Is there guidance on slot0 device identity key vs slot1 IAK for Quote verification?
Or is reusing the same cert chain for all slots acceptable for the reference TPM stub?
(Note: libspdm_read_responder_public_certificate_chain_per_slot() currently reads TPM_RESP_CERT_CHAIN regardless of slot_id.)
-
Roadmap
Are there existing issues, design notes, or planned work to add Quote / IAK / real Event Log to spdm_device_secret_lib_tpm?
Summary
I am integrating platform attestation with TPM as the Root of Trust on top of libspdm / spdm-emu and would like to understand the design intent behind the current TPM-backed measurement path.
Today, the TPM stub (
spdm_device_secret_lib_tpm) appears to:Esys_PCR_Readand place digests intoGET_MEASUREMENTS.measurement_record[]as DMTF measurement blocks (libspdm_fill_measurement_image_hash_block()inmeas.c).TPM_RESP_KEY) whenSignatureRequested=1(libspdm_generate_measurement_signature()→libspdm_responder_data_sign()).libspdm_measurement_opaque_data()as a placeholder (sequential bytes0,1,2,...) with noTPM2_Quote, no IAK / attestation key, and noTPM2B_ATTESTinopaque_data.Provisioning (
setup-tpm.sh,keys.h) also defines onlyTPM_RESP_KEY/TPM_RESP_CERT_CHAIN(slot0), not a separate IAK for attestation.Current vs expected behavior
What the code does today
libspdm_tpm_read_pcr()→Esys_PCR_Readcryptlib_openssl/tpm/tpm.cmeasurement_record[]spdm_device_secret_lib_tpm/meas.cTPM_RESP_KEYsigns SPDM L1/L2 transcriptsign.c,libspdm_rsp_measurements.c0,1,2,...; no Quotemeas.c→libspdm_measurement_opaque_data()keys.h,setup-tpm.shWhat I expected for TPM-rooted platform attestation
GET_MEASUREMENTS.measurement_record[]TPM2B_ATTEST+TPMT_SIGNATURE)GET_MEASUREMENTS.opaque_data[](e.g. OpaqueDataFmt1 + TCG element)GET_CERTIFICATEslot1 (separate from device identity)GET_MEASUREMENT_EXTENSION_LOG.mel[]Quote qualifying data would bind to
GET_MEASUREMENTSrequestnonce[32], not the response nonce.Important distinction:
MEASUREMENTS.signaturecovers the SPDM transcript (device identity). TPM Quote should not replace that field; it attests PCR state via the TPM attestation key (IAK).Questions for maintainers
Was omitting
TPM2_Quoteintentional?Is the current model (“PCR in
measurement_record+ device key signs SPDM transcript”) considered sufficient for “TPM-backed measurements” in libspdm’s scope?Trust boundary
Without Quote, how should a verifier distinguish:
SPDM field semantics
Should TPM Quote live in
MEASUREMENTS.opaque_data(not insignature)?Is there an upstream preference for
SPDM_REGISTRY_ID_TCG+TPM2B_ATTEST || TPMT_SIGNATUREunder OpaqueDataFmt1?Key separation
Is there guidance on slot0 device identity key vs slot1 IAK for Quote verification?
Or is reusing the same cert chain for all slots acceptable for the reference TPM stub?
(Note:
libspdm_read_responder_public_certificate_chain_per_slot()currently readsTPM_RESP_CERT_CHAINregardless ofslot_id.)Roadmap
Are there existing issues, design notes, or planned work to add Quote / IAK / real Event Log to
spdm_device_secret_lib_tpm?