mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jiri Pirko <jiri@resnulli.us>
To: linux-coco@lists.linux.dev
Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org,
	x86@kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org,
	jgg@ziepe.ca, david.quigley@intel.com, lukas@wunner.de,
	ksinyuk@kernel.org, rodrigo.vivi@intel.com,
	cedric.xing@intel.com, sameo@meta.com, drdeeglaze@gmail.com,
	James.Bottomley@HansenPartnership.com, aik@amd.com,
	jpiotrowski@nvidia.com, qinkun@google.com, pgonda@google.com,
	jic23@kernel.org, alistair.francis@wdc.com, ankita@nvidia.com,
	suzuki.poulose@arm.com, kas@kernel.org,
	rick.p.edgecombe@intel.com, elena.reshetova@intel.com,
	dave.hansen@linux.intel.com,
	sathyanarayanan.kuppuswamy@linux.intel.com, peter.fang@intel.com,
	jarkko@kernel.org, zohar@linux.ibm.com, yeoreum.yun@arm.com,
	aneesh.kumar@kernel.org, dave.jiang@intel.com,
	nik.borisov@suse.com, sergii.dmytruk@3mdeb.com
Subject: [PATCH RFC v2 0/9] attestation: Add a common subsystem and TDX support
Date: Fri, 13 Nov 2026 17:08:29 +0100	[thread overview]
Message-ID: <20261113160838.2512652-1-jiri@resnulli.us> (raw)

From: Jiri Pirko <jiri@nvidia.com>

Linux has several attestation interfaces, each tied to one technology.
Extending a measurement takes device-specific flows for TPM, CCA, TDX
and SEV, none of them discoverable, and requesting a signed quote takes
another set, SPDM included. A new root of trust has no logical home
short of squeezing it into tsm_report and tsm_mr: tsm_report covers
reports alone, the MRs went to tsm_mr, and SPDM fits neither.

This series adds a common attestation subsystem. Its goal is to support
platform, TEE and device roots of trust through one model, including
TPM2, TDX, SEV-SNP, Arm CCA, FIRME, Caliptra and PCI/TSM-backed
devices, so that a program extends a register or asks for evidence
without knowing the hardware behind it. This first series implements
the common subsystem and a TDX provider. The native TDX interfaces,
/dev/tdx_guest, tsm_report and tsm_mr, stay as they are.

RFC v1 [1] posted this and CTLV as one patchset. For convenience, v2
splits it in two, and this series applies on top of the CTLV series,
posted alongside as

  [PATCH RFC v2 00/15] ctlv: Add a schema-driven TLV uAPI for character devices

Each attestation device has a node, /dev/attestation/attestationN,
that speaks CTLV: a request is checked against the family's schema and
executed at once, rather than assembled through several files. The
base family, ctlv-attestation, has what every provider shares, so a
tool written against it works with any provider. TDX's family,
ctlv-attestation-tdx, inherits it and adds no ops. It fills the base
family's extension points: device-get's info with the TD's MRCONFIGID,
MROWNER and MROWNERCONFIG, and evidence-vendor-format with the two TDX
Quote formats.

The base family's ops, as ctlvgen --signatures prints them, with the
purpose of each:

  # What the device supports, fixed for its life, and its family's fields.
  device-get() ->
      { caps: { evidence?: { objects[16]: { id, class, formats[4]?,
                                            vendor-formats[4]?, max-length,
                                            challenge-lengths[8]?: { length?,
                                                                     min-length?,
                                                                     max-length? } } },
                mr?: { flags } }, info: device-info }

  # Evidence: each object named, written to a blob the caller supplies,
  # a signed one made by the call over the challenge.
  evidence-get(challenge?, objects[16]: { id, data: out blob }) ->
      { results[16]: { format?, vendor-format?, length }, mr-generation? }

  # Describe every MR, or the one an ID names.
  mr-get(id?) -> { items[]: { id, mr-desc } }

  # One MR's values, a digest per bank, and the MR generation they
  # reflect.
  mr-read(id) -> { mr-generation, mr-values[hash-algo]: mr-value }

  # Extend banks of one MR by the caller's digests.
  mr-extend(id, mr-values[hash-algo]: mr-value) -> { mr-generation }

An mr-desc is an MR's name, its banks, what it allows and its register
index, and an mr-value one bank's hash algorithm and digest. The
userspace ABI gives each op's request, reply, errors and access.

On TDX, evidence-get returns the Quote over a 64-byte challenge,
labelled a legacy or a DICE one, and, where ACPI describes it, the
CCEL event log. The MRs are MRTD, which cannot be extended, and RTMR0
to RTMR3, all SHA-384. With ctlvctl from the CTLV series and
CTLV_SPEC_DIR pointing at Documentation/ctlv/specs, the simulator's
output, rewritten for a TD, its lengths left out:

  # The device and its family chain.
  $ ctlvctl list
  attestation/attestation0        ctlv/ctlv-attestation/ctlv-attestation-tdx

  # What it supports.
  $ ctlvctl exec attestation/attestation0 device-get
  # device-get, 1 fragment, generation 0
    device-get caps
      device-get caps.evidence
        device-get caps.evidence.objects
          device-get caps.evidence.objects.id 0
          device-get caps.evidence.objects.class signed
          device-get caps.evidence.objects.vendor-formats quote
          device-get caps.evidence.objects.vendor-formats quote-dice
          device-get caps.evidence.objects.max-length 131048
          device-get caps.evidence.objects.challenge-lengths
            device-get caps.evidence.objects.challenge-lengths.length 64
        device-get caps.evidence.objects
          device-get caps.evidence.objects.id 1
          device-get caps.evidence.objects.class event-log
          device-get caps.evidence.objects.formats ccel
          device-get caps.evidence.objects.max-length ...
      device-get caps.mr
        device-get caps.mr.flags extend
    device-get info
      device-info.mrconfigid hex:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
      device-info.mrowner hex:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
      device-info.mrownerconfig hex:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

  # A Quote over a 64-byte nonce, written to quote.bin.
  $ nonce=$(openssl rand -hex 64)
  $ ctlvctl exec attestation/attestation0 evidence-get --json \
          '{"challenge":"hex:'"$nonce"'",
            "objects":[{"id":0,"data":{"file":"quote.bin"}}]}'
  # evidence-get, 1 fragment, generation 0
    mr-generation 0
    evidence-get results
      evidence-get results.vendor-format quote
      evidence-get results.length ...

  # Every MR.
  $ ctlvctl exec attestation/attestation0 mr-get
  # mr-get, 1 fragment, generation 0
    mr-get items
      mr-get items.id 0
      mr-desc.name mrtd
      mr-desc.supported-hash-algorithms HASH_ALGO_SHA384
      mr-desc.caps 0
    mr-get items
      mr-get items.id 1
      mr-desc.name rtmr0
      mr-desc.supported-hash-algorithms HASH_ALGO_SHA384
      mr-desc.register-index 0
      mr-desc.caps extend
    ...

  # The value of RTMR0, MR 1.
  $ ctlvctl exec attestation/attestation0 mr-read id=1
  # mr-read, 1 fragment, generation 0
    mr-generation 0
    mr-values
      mr-value.hash-algo HASH_ALGO_SHA384
      mr-value.data hex:b57a300eac0c9b8593bafbadee812f8915456913c28010dab20d700446169bdd56e1af87ce94d66c8fd2d456b3e42826

  # Extend RTMR3, MR 4, by a file's SHA-384 digest.
  $ digest=$(sha384sum app.img | cut -d' ' -f1)
  $ ctlvctl exec attestation/attestation0 mr-extend --json \
          '{"id":4,"mr-values":[{"hash-algo":"HASH_ALGO_SHA384",
                                 "data":"hex:'"$digest"'"}]}'
  # mr-extend, 1 fragment, generation 0
    mr-generation 1

This series is the first part. The branch [2] has the whole work,
building on it: CTLV's events, the MR journal with IMA as its first
user, memfd and dma-buf evidence blobs, an mr-extend that hashes the
caller's data, evidence acceptance and device security, a simulation
provider, KUnit tests and selftests.

The series adds 3480 lines:

  attestation core, C               1340
  generated files                    770
  TDX provider, C                    470
  docs                               462
  family specifications              206
  ABI snapshots                      170
  registry, build                     62

Changes since RFC v1, each patch listing its own:

- Each evidence object has an ID, a class, signed or event-log, and
  the formats it may have: from evidence-format for a layout a
  standard defines, from evidence-vendor-format, whose values the
  device's family gives, for a vendor's. A signed object lists the
  challenge lengths it takes.
- evidence-get names objects by ID, may omit the challenge, and takes
  output blobs of any length, failing with the length one needs.
- TDX labels each Quote, returns the CCEL log, and leaves the
  TDREPORT to /dev/tdx_guest.
- The MR journal and its notifications are left out, until IMA uses
  the subsystem.
- mr-extend may extend some of an MR's banks, and every MR can be
  read.
- mr-get, a query, describes every MR or the one its optional id
  names, and mr-dump is gone.
- Attestation has its own class and /dev/attestation/ nodes, and the
  TDX provider is part of tdx-guest instead of a module of its own.
- The specs are written as op trees and records, with a comment on
  every item, and a userspace ABI document describes the family.

The patches:

  1      the base family's specification and generated files
  2      the userspace ABI
  3-5    the provider and instance core, the MRs, and the CTLV ops
  6      how to write a provider
  7      tdx-guest's native attestation service, for the provider
  8-9    the TDX family's specification and implementation

Note to reviewers: the uAPI, in 1 and 2, and the provider API, in 3
and 6, matter most at this stage.

[1] https://lore.kernel.org/all/20261015145053.3664509-1-jiri@resnulli.us/
[2] https://github.com/jpirko/linux_mlxsw/commits/wip_attestation_all_2

Jiri Pirko (9):
  attestation: Add the base family specification and generated files
  Documentation: attestation: Add userspace ABI
  attestation: Prepare provider and instance core
  attestation: Prepare measurement registers
  attestation: Add CTLV operation handling
  Documentation: attestation: Describe how to write a provider
  tdx-guest: Expose the native attestation service API
  attestation: Add the TDX family specification and generated files
  attestation: Add the TDX family implementation

 .../ctlv/abi/ctlv-attestation-tdx.yaml        |  21 +
 Documentation/ctlv/abi/ctlv-attestation.yaml  | 147 +++++
 Documentation/ctlv/abi/families.registry.yaml |   2 +
 Documentation/ctlv/families.yaml              |   2 +
 Documentation/ctlv/generated-files.yaml       |  14 +
 .../ctlv/specs/ctlv-attestation-tdx.yaml      |  25 +
 .../ctlv/specs/ctlv-attestation.yaml          | 181 +++++++
 Documentation/driver-api/attestation.rst      |  99 ++++
 Documentation/driver-api/index.rst            |   1 +
 .../userspace-api/attestation-tdx.rst         |  59 +++
 Documentation/userspace-api/attestation.rst   | 294 ++++++++++
 Documentation/userspace-api/index.rst         |   1 +
 Documentation/virt/coco/tdx-guest.rst         |   8 +
 MAINTAINERS                                   |  13 +
 drivers/Kconfig                               |   2 +
 drivers/Makefile                              |   1 +
 drivers/attestation/Kconfig                   |  16 +
 drivers/attestation/Makefile                  |   5 +
 drivers/attestation/core/core.c               | 500 ++++++++++++++++++
 drivers/attestation/core/ctlv.c               | 499 +++++++++++++++++
 drivers/attestation/core/internal.h           |  34 ++
 drivers/attestation/core/mr.c                 |  64 +++
 .../generated/ctlv_attestation_gen.c          | 179 +++++++
 .../generated/ctlv_attestation_gen.h          | 204 +++++++
 drivers/virt/coco/tdx-guest/Kconfig           |   4 +-
 drivers/virt/coco/tdx-guest/Makefile          |   6 +
 drivers/virt/coco/tdx-guest/attestation.c     | 313 +++++++++++
 .../coco/tdx-guest/ctlv_attestation_tdx_gen.c |  65 +++
 .../coco/tdx-guest/ctlv_attestation_tdx_gen.h |  44 ++
 drivers/virt/coco/tdx-guest/internal.h        |  48 ++
 .../coco/tdx-guest/{tdx-guest.c => main.c}    | 137 ++++-
 include/linux/attestation.h                   | 243 +++++++++
 include/uapi/ctlv/ctlv_attestation_gen.h      | 234 ++++++++
 include/uapi/ctlv/ctlv_attestation_tdx_gen.h  |  42 ++
 include/uapi/ctlv/ctlv_families_gen.h         |   2 +
 35 files changed, 3480 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/ctlv/abi/ctlv-attestation-tdx.yaml
 create mode 100644 Documentation/ctlv/abi/ctlv-attestation.yaml
 create mode 100644 Documentation/ctlv/specs/ctlv-attestation-tdx.yaml
 create mode 100644 Documentation/ctlv/specs/ctlv-attestation.yaml
 create mode 100644 Documentation/driver-api/attestation.rst
 create mode 100644 Documentation/userspace-api/attestation-tdx.rst
 create mode 100644 Documentation/userspace-api/attestation.rst
 create mode 100644 drivers/attestation/Kconfig
 create mode 100644 drivers/attestation/Makefile
 create mode 100644 drivers/attestation/core/core.c
 create mode 100644 drivers/attestation/core/ctlv.c
 create mode 100644 drivers/attestation/core/internal.h
 create mode 100644 drivers/attestation/core/mr.c
 create mode 100644 drivers/attestation/generated/ctlv_attestation_gen.c
 create mode 100644 drivers/attestation/generated/ctlv_attestation_gen.h
 create mode 100644 drivers/virt/coco/tdx-guest/attestation.c
 create mode 100644 drivers/virt/coco/tdx-guest/ctlv_attestation_tdx_gen.c
 create mode 100644 drivers/virt/coco/tdx-guest/ctlv_attestation_tdx_gen.h
 create mode 100644 drivers/virt/coco/tdx-guest/internal.h
 rename drivers/virt/coco/tdx-guest/{tdx-guest.c => main.c} (79%)
 create mode 100644 include/linux/attestation.h
 create mode 100644 include/uapi/ctlv/ctlv_attestation_gen.h
 create mode 100644 include/uapi/ctlv/ctlv_attestation_tdx_gen.h

-- 
2.56.0


             reply	other threads:[~2026-11-13 16:08 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13 16:08 Jiri Pirko [this message]
2026-11-13 16:08 ` [PATCH RFC v2 1/9] attestation: Add the base family specification and generated files Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 2/9] Documentation: attestation: Add userspace ABI Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 3/9] attestation: Prepare provider and instance core Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 4/9] attestation: Prepare measurement registers Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 5/9] attestation: Add CTLV operation handling Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 6/9] Documentation: attestation: Describe how to write a provider Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 7/9] tdx-guest: Expose the native attestation service API Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 8/9] attestation: Add the TDX family specification and generated files Jiri Pirko
2026-11-13 16:08 ` [PATCH RFC v2 9/9] attestation: Add the TDX family implementation Jiri Pirko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261113160838.2512652-1-jiri@resnulli.us \
    --to=jiri@resnulli.us \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=aik@amd.com \
    --cc=alistair.francis@wdc.com \
    --cc=aneesh.kumar@kernel.org \
    --cc=ankita@nvidia.com \
    --cc=cedric.xing@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dave.jiang@intel.com \
    --cc=david.quigley@intel.com \
    --cc=drdeeglaze@gmail.com \
    --cc=elena.reshetova@intel.com \
    --cc=jarkko@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=jic23@kernel.org \
    --cc=jpiotrowski@nvidia.com \
    --cc=kas@kernel.org \
    --cc=ksinyuk@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=nik.borisov@suse.com \
    --cc=peter.fang@intel.com \
    --cc=pgonda@google.com \
    --cc=qinkun@google.com \
    --cc=rick.p.edgecombe@intel.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=sameo@meta.com \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=sergii.dmytruk@3mdeb.com \
    --cc=suzuki.poulose@arm.com \
    --cc=x86@kernel.org \
    --cc=yeoreum.yun@arm.com \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®