[Seat] Re: A continuity-and-revocation layer above attested TLS, with running code

Serhii Nikolaichuk <nikolaichuk.s.f@gmail.com> Mon, 21 September 2026 23:43 UTC

Received: from mail-wm2-x11.google.com (mail-wm2-x11.google.com [IPv6:2a00:1450:4864:31::11]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by mx.ietf.org (Postfix) with ESMTPS id 7F00942 for <seat@ietf.org>; Mon, 21 Sep 2026 23:43:20 +0000 (UTC)
Authentication-Results: mx.ietf.org; dkim=pass header.d=gmail.com header.s=20251104 header.b="P/95gG4Q"; arc=pass ("google.com:s=arc-20260327:i=1"); dmarc=pass (policy=none) header.from=gmail.com; spf=pass (mx.ietf.org: domain of nikolaichuk.s.f@gmail.com designates 2a00:1450:4864:31::11 as permitted sender) smtp.mailfrom=nikolaichuk.s.f@gmail.com
Received: by mail-wm2-x11.google.com with SMTP id 5b1f17b1804b1-49cd5462b69so19020775e9.1 for <seat@ietf.org>; Mon, 21 Sep 2026 16:43:20 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1790034199; cv=none; d=google.com; s=arc-20260327; b=WgkP+KIXsSOncufeExLMzx8zg6/s4obeSQEV+mXKUiEw3uDslpSytdLC7bYe1FfROr owvBfZNgFS1qpYmrRd4YSVf5U4LRfJD8QBAqwiOHdFJRri6mo6/ttxYvNKOSDYD2i80l d1wBxUrwdOWCGXEf1uJCoBl8x95E0ZEfRzjT/h284z/rms4aazOQUVqbCrl6ERtZ0sXX HIsUUyoSZjIhZ2WTGO/4as8ipYHPkl0sZxKQLUtOlPooV7lUGh+PTH6JOWoaM1CwsMy1 +yowZ6kciSKx+TYU0RjL373njs6D6RbvXJP5sawC6SeXQ6HXHr5EpCyeohsc/2XOqstg Lr0A==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:subject:message-id:date:mime-version:references:in-reply-to :from:dkim-signature; bh=hbHZLo6e2K5g9cuKNC1n+uBF+g15jcZMA+wUc4K5kyA=; fh=az4wCPSSRZNH9/Fdfgdg9kgBopcXCf3MFpA+F0EQCME=; b=Hy7bixqpsPHoCPlcbPWVpcGe82G9DkImzbW6dh7258kn8V9vh6KrUtJUW7TdEHnHy1 jRlHpzhVnpbxrzg3i+Lb0Efqmj1FzKulfspSOHGLjPxwtXIX0OIOr/6Lo7QZ9bPzBasL BRsbmuWUw/vgm9VJNe3/KIqntWm9yvJxaloYjHyL/8hBz1x4hFzF3Pag4FnOZuLk/e8/ 2fS/SVt8geoE1yIXuQxdzQhVYtqZOYPJyUnNxy8bYDwX6Ij0KbEbFSGXxl+K0e4qskEr GiF8k+pRXvvjc+hxoMyEazZMPHbxTCXImsD5e00nMIbZWpdmCDURLcrN3qUQrZb+3WBn 68qA==; darn=ietf.org
ARC-Authentication-Results: i=1; mx.google.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790034199; x=1790638999; darn=ietf.org; h=content-type:cc:to:subject:message-id:date:mime-version:references :in-reply-to:from:from:to:cc:subject:date:message-id:reply-to :content-type; bh=hbHZLo6e2K5g9cuKNC1n+uBF+g15jcZMA+wUc4K5kyA=; b=P/95gG4QxNzETkCQNv4LNxSGj9BiX6VnSlSZ2/rhEY+a4AccBu5w8NphYN/27DYq/7 TVteKV0dWR+U00iXYTOQIy7gzugcDWneH20KVpZfHmy0caKxar5fryIrhBb1ymkOCKVT EEmPYjBIPcOQ8sZpLmSin+Rvm7ggM4lhr5JAm55htSGZ7CGuQI0Zzt5SCrXorLzBdBDc HVVwrq+9BPz1pNjoTB+1RKAJMTb033W6oDtr57S52L7pVWYZgqnwNfblZvpNIIrJM4TV jAYz/QMBCHpuC6SaNDTsWt0Jb+J2S84BPohbdZIBcnx9vOHhJZMry7L2FmuqOHcQVVV2 sKrw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790034199; x=1790638999; h=content-type:cc:to:subject:message-id:date:mime-version:references :in-reply-to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hbHZLo6e2K5g9cuKNC1n+uBF+g15jcZMA+wUc4K5kyA=; b=DKLJGSsbMf/s0puqYAzlPA6WRyqbPxLmhJABpsqPfEiJxbdUXg11CAuutXjYv/iXNI oAOdqo7RAAXzxaF9dEkMJgeRIspkfWZx4kzr7fScu463dtyoeU8QlHe3ZXvA+8jhxIF8 1h1lp+LZiA9mCmtH2AJTbLfQOc1xlVksD9HyfD7BvYtKDoh5sz6AJOpmFmaUJj/CYWtI pYatFDOwTrVlWVV7iI/xSDbHanXf+bhFGGVWqjLru4UoHCBzpj0sLSedNwyzZWr2752Y iqrB1/+TeOaca+JAP28RAPEBxE5lvLVNzrCIJJbD5cd9aFnoq2FVFWiHXCwAGGyvNIp+ +CjQ==
X-Gm-Message-State: AFuF++mg+6KJihouKKqD4b9KK/wUSz/xA0ikyDZOqhtjP7+HHRkKs9i7 DCSEYWRTdq2a9tTWb14/dKAXuif46HqBf5Y3j20JRCZDhQxepfYqGmTvRvTVDycJkG4Cz6D4IXa LzC0FcJ+s/yhJgHAKwqs50YOgOp7Nb9QWvdI=
X-Gm-Gg: AYBFou0n5UToKEvb2lOa/sSbLwpiWnHfu1rqi1T2Lu0lkeU5Sr2CBDQSmucOZASWA+T /sc0RNokpDMBUc89LEALyJXR9JrhDLKefsrvlTxIgH04wNFbXBwxa5E1kzu1BtklKsjAH8GR+M+ sHZiSWcF601fIG+YXC6ZHxLUN37z5QCJlISH6L8AUsxUtyRUg15vEtxee76bGHqwya2GW2U+qVA v7UtNbzkeq1MilurHrj9wYhQh49l66yR7yq7bofuUq80Vr+9NHfozHWO6fq77FSsb5/TgHEJA3W ZXVxwEKDgC/SjExvVRBYJm85yZd0wWKVKif8rrpRMtQIDusxIEI5yj1m5wf2T+z53jtpX9YAKwO XVKEasOj3MetfADOZu8M+6bjP6be2EmeKt0p54doBrLstKZBKnitn5EpIE0sP1s/Fb+FfTtcb3V KlsO5INciryVR68UUT3I8=
X-Received: by 2002:a05:600c:c0c3:10b0:49e:823a:9dec with SMTP id 5b1f17b1804b1-49fc5a10b5fmr160083715e9.3.1790034199173; Mon, 21 Sep 2026 16:43:19 -0700 (PDT)
Received: from 101988054943 named unknown by gmailapi.google.com with HTTPREST; Mon, 21 Sep 2026 16:43:18 -0700
Received: from 101988054943 named unknown by gmailapi.google.com with HTTPREST; Mon, 21 Sep 2026 16:43:17 -0700
From: Serhii Nikolaichuk <nikolaichuk.s.f@gmail.com>
In-Reply-To: <CADj3X6vQ44rRA3LN+MZBY6gp93Rrx=Vt1tf-nsXcxKerhNx3jQ@mail.gmail.com>
References: <CADj3X6vQ44rRA3LN+MZBY6gp93Rrx=Vt1tf-nsXcxKerhNx3jQ@mail.gmail.com>
MIME-Version: 1.0
Date: Mon, 21 Sep 2026 16:43:18 -0700
X-Gm-Features: AcwNN1V_tqv-CW_bzFrO48X0EalhzLZf_lonBpPmti6EPXEnFXbGP8M1bKtilTE
Message-ID: <CADj3X6sAUvyv=WWz-_FE27KXqNKeedM22eJVz0tUbWns=w5yTw@mail.gmail.com>
To: rats@ietf.org
Content-Type: multipart/alternative; boundary="00000000000093dcb9065c06d08f"
X-Spamd-Bar: -
Message-ID-Hash: ZHAO6OLCF3LJFBUOXHQLQDOIEMPWWUTX
X-Message-ID-Hash: ZHAO6OLCF3LJFBUOXHQLQDOIEMPWWUTX
X-MailFrom: nikolaichuk.s.f@gmail.com
X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-seat.ietf.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
CC: seat@ietf.org
X-Mailman-Version: 3.3.10
Precedence: list
Subject: [Seat] Re: A continuity-and-revocation layer above attested TLS, with running code
List-Id: "Secure Evidence and Attestation Transport (SEAT) WG" <seat.ietf.org>
Archived-At: <https://mailarchive.ietf.org/arch/msg/seat/KwtGScLIYvUCW2A0HxAS5s9XMMo>
List-Archive: <https://mailarchive.ietf.org/arch/browse/seat>
List-Help: <mailto:seat-request@ietf.org?subject=help>
List-Owner: <mailto:seat-owner@ietf.org>
List-Post: <mailto:seat@ietf.org>
List-Subscribe: <mailto:seat-join@ietf.org>
List-Unsubscribe: <mailto:seat-leave@ietf.org>

Three corrections to what I wrote this morning, and one question that
turned out
to matter more than the layer I was describing.

A review of the code found that my reference client defeated my own claims:
it
read the RFC 8446 exporter and the identity key out of the peer's message
rather
than deriving them from its own side of the session, which is exactly what a
relay forwards unchanged. Everything I said about relay resistance was
therefore
untested by the client that shipped. It is fixed, there is now a real TLS
relay
in the test suite, and I would rather say this here than have someone find
it.
It is also the same class of defect this list discussed in July under
"formal
analysis of relay attacks in attested TLS" (CVE-2026-33697) -- found this
time
by reading my own reference client rather than someone else's.

Two claims in that message were also stronger than the mechanism:

- I said a stolen key on a second genuine chip is caught "and the identity
revoked". Revoking on fork is an attack on the victim: anyone presenting a
stolen key from any genuine chip could destroy the identity being
impersonated. The impostor is now refused and the victim keeps serving;
revocation is an explicit operator act.

- I said I had measured the physical-insider window at "about 8 ms per
liveness beacon". That number is the beacon cadence, which bounds how finely
an interruption can be seen. It is not the attacker's window: while the key
is in cleartext in guest memory to sign at all, that window is the life of
the process.

I should also withdraw the framing. What I have is post-handshake: the
evidence
binds the exporter, which exists only after the handshake completes, so
calling
it a floor under both transports overstated it.

The question that turned out to matter

Continuity needs a claim that says "the same instance". Implementations
reach
for CHIP_ID, mine included. Measuring an archive of 93 SEV-SNP reports from
three clouds, and then two clouds live, says that is the wrong granularity:

- CHIP_ID identifies silicon. Five chips in the corpus each carried between
two and four distinct guests, so re-hosting between VMs on one socket is
invisible to it.

- Under a shared-tenancy VLEK it is absent. Six AWS instances report 64 zero
bytes, and MASK_CHIP_KEY is CLEAR in all of them: the platform hides the
identifier without setting the flag that says so. On the same platform the
VLEK signing key is shared region-wide, so neither the chip nor the
signature separates two machines.

- REPORT_ID does. It is present on all three clouds, distinct for every
instance including guests sharing a socket, and per the Firmware ABI 1.54
the AMD-SP generates it and it is not among the SNP_LAUNCH_START inputs, so
the hypervisor cannot choose it.

draft-deeglaze-amd-sev-snp-corim-profile states the ambiguity plainly --
"the
instance identifier can be argued as any of REPORT_ID, REPORT_ID_MA when
non-zero, CHIP_ID (for VCEK), or CSP_ID (for VLEK)" -- and chooses CHIP_ID,
which is right for the question it asks: the instance of the Attesting
Environment, and that is the AMD-SP. Continuity asks about the Target
Environment. The gap is not that the profile is wrong; it is that
implementations reuse the attester's identity as the target's, because only
one
of the two has been written down. The substitution is silent: a verifier
anchored on CHIP_ID under a masked platform compares 64 zero bytes to 64
zero
bytes and reports a match.

On TDX the answer appears to be that no such claim exists. Two TDs launched
from
one image differ in exactly one TDREPORT field, MROWNER, and the host VMM
supplies that one through KVM_TDX_INIT_VM. A design that anchors on SEV-SNP
does
not port to TDX by renaming a field.

One interoperability note worth its own line

AMD signs ASK and ARK with RSASSA-PSS and encodes trailerField=1 explicitly.
That is the DEFAULT value, which X.690 11.5 forbids in DER, so a strict
ASN.1
parser refuses to load the AMD certificate chain at all. A verifier that
treats
"cannot parse the root" as "skip the root" silently falls back to trusting
whatever key signed the report. I suspect this is one reason chain
validation is
so often absent in attestation code; mine was. Checked against the live KDS
endpoint on 21 September 2026.

What is and is not established

The code is at
https://www.google.com/url?q=https://github.com/nikolaichuk7/hatls&source=gmail&ust=1790120597741000&sa=E
with the audit of its own
defects, the hardware logs unedited including the runs whose conclusions no
longer hold, and the measurements above reproducible from the corpus. A
ProVerif
model covers the binder and one step of the mandate's appraisal; it does not
cover the transfer grant, revocation, the ledger, receipts, or TLS, and I
would
rather state that here than let "there is a formal model" do work it cannot
do.

The thing I would like the working group's view on is not my layer. It is
whether instance identity for a Target Environment should be specified at
all,
and if so which claim carries it on SEV-SNP, TDX and Nitro. Getting it
wrong is
not loud.

Serhii Nikolaichuk
The Capital Index, Austin, Texas

On Mon, Sep 21, 2026 10:02 AM, Serhii Nikolaichuk <nikolaichuk.s.f@gmail.com>
wrote:

> Dear RATS, and SEAT in copy,
>
> Ned invited, in the KIA/GAR thread, drafts that show how continuity
> objectives
> can be achieved within RATS attestation infrastructure. This is one, with
> running code rather than a proposal, and I think it also lightens a choice
> the
> SEAT working group is weighing, so I have copied SEAT.
>
> The SEAT discussion is between binding attestation inside the TLS handshake
> (draft-fossati-seat-early-attestation) and after it
> (draft-fossati-seat-expat).
> Both are good and both bind a single moment. Neither is at fault for what
> draft-ietf-seat-use-cases states directly: Section 3.8.1 asks for
> "continuity
> with a particular platform instance ... a means to reject compromised
> authentication credentials" and leaves the mechanism open; Section 4.8 says
> current systems "do not achieve" continuous assurance. That missing layer
> is a
> RATS matter, not a transport one: it is enrolment (TACRA,
> draft-novak-rats-tacra), a continuity chain (the shape of
> draft-nikolaichuk-scitt-continuity-receipts), and revocation.
>
> So rather than argue intra versus post, I built the continuity layer and
> let
> both sit underneath it, unchanged:
>
> intra_link = f(transcript, identity key) # the early binder, in the
> handshake
> post_link_n = f(exporter, prev_link, counter) # the post binder, on the
> shared secret
> each link is carried in a hardware attestation report; a shared mandate
> admits
> one continuous, ordered, chip-consistent chain per identity, enrols the
> key to
> its birth chip, and revokes on fork.
>
> Measured on real AMD SEV-SNP hardware, not modelled:
>
> - a stolen identity key presented on a second genuine chip is caught and
> the
> identity revoked;
> - with enrolment, that stolen key is rejected on the FIRST message, no
> second
> observation needed (this is the 3.8.1 mitigation, made concrete);
> - the one case no key management can close, a physical insider on the
> enrolled
> chip, I did not claim to close; I measured its window instead, about 8 ms
> per
> liveness beacon on the chip.
>
> What this offers SEAT is not a third camp but a floor under both: early
> and post
> attestation are the two ends of the same continuity chain, and the choice
> between them stops carrying the whole security argument once the chain and
> the
> mandate are there.
>
> The continuity layer here is an independent implementation in that
> repository, not a
> wrapper over anything I keep private; every number above reproduces from
> the public
> code alone. Clone it, bring your own confidential VM, and run the full
> cycle, or run
> it locally against a mock chip. There is an attack playground for trying
> to defeat the
> mandate. If a measurement is wrong, it is wrong in a way you can show by
> running it,
> which is the point of putting it there rather than asserting it:
>
> https://www.google.com/url?q=https://github.com/nikolaichuk7/hatls&source=
> gmail&ust=1790089353332000&sa=E
>
> You can also compose it with either transport directly: early attestation
> and expat are
> open, the continuity layer is open, and the seam between them is the two
> links above, so
> a full end-to-end check needs nothing from me.
>
> One interest I should declare plainly, because it bears on why I am not
> taking a
> side. I am a co-author of draft-intra-handshake-fail, which analysed early
> attestation and found real weaknesses in it. That is exactly why I want to
> be clear
> that this layer is not built against either transport. It carries both
> unchanged as
> the two ends of one chain; it does not depend on the intra-versus-post
> choice and does
> not try to settle it. My neutrality here is structural, not diplomatic:
> the continuity
> layer sits above the binder, so it does not care which binder is
> underneath, and I
> would rather it strengthen whichever the working group prefers than argue
> that question
> again.
>
> I would rather this become one document with whoever wants to carry it
> than a draft
> standing apart, and I am just as interested in where it breaks as in where
> it holds.
>
> Serhii Nikolaichuk
> The Capital Index, Austin, Texas
>