Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH v2 0/1] KVM: selftests: SEV: Sanity check the launch measurement
@ 2026-08-11  4:08 Hemanth Selam
  2026-08-11  4:08 ` [PATCH v2 1/1] " Hemanth Selam
  0 siblings, 1 reply; 3+ messages in thread
From: Hemanth Selam @ 2026-08-11  4:08 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini, Shuah Khan
  Cc: kvm, linux-kselftest, linux-kernel

This replaces the TODO in test_sev() with a sanity check of the launch
measurement returned by KVM_SEV_LAUNCH_MEASURE.  A full attestation-style
validation isn't possible from the selftest because userspace does not
possess the transport keys the PSP uses to derive the measurement.  The
check therefore verifies the firmware-reported blob length and that the
measurement and the nonce are non-zero, with the blob layout described by
a struct so the buffer and field sizes derive from a single definition.

No functional changes from v1; this posting only adds a cover letter.

v1: https://lore.kernel.org/all/20260807121308.1885737-1-hemanth.selam@gmail.com/

Hemanth Selam (1):
  KVM: selftests: SEV: Sanity check the launch measurement

 tools/testing/selftests/kvm/include/x86/sev.h | 12 +++++++
 tools/testing/selftests/kvm/lib/x86/sev.c     | 11 +++++--
 .../selftests/kvm/x86/sev_smoke_test.c        | 33 +++++++++++++++++--
 3 files changed, 52 insertions(+), 4 deletions(-)

-- 
2.43.7


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 1/1] KVM: selftests: SEV: Sanity check the launch measurement
  2026-08-11  4:08 [PATCH v2 0/1] KVM: selftests: SEV: Sanity check the launch measurement Hemanth Selam
@ 2026-08-11  4:08 ` Hemanth Selam
  2026-08-26  5:04   ` Hemanth Selam
  0 siblings, 1 reply; 3+ messages in thread
From: Hemanth Selam @ 2026-08-11  4:08 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini, Shuah Khan
  Cc: kvm, linux-kselftest, linux-kernel

test_sev() launches the guest but discards the measurement returned by
KVM_SEV_LAUNCH_MEASURE, with a TODO to validate it.  A full
attestation-style validation isn't possible from the selftest because
userspace does not possess the transport keys the PSP uses to derive the
measurement, so the expected value cannot be recomputed here.

Capture the measurement for SEV and SEV-ES guests and sanity check it:
assert that the firmware reports the blob length defined by the SEV API
specification, and that both the measurement and the nonce are non-zero.
Describe the blob layout with a struct so the buffer and field sizes are
derived from a single definition instead of open-coded magic numbers.
SNP does not return a measurement through this path, so it is skipped.

  # ./sev_smoke_test; echo "exit=$?"
  Random seed: 0x6b8b4567
  exit=0

  # ./sev_init2_tests; echo "exit=$?"
  Random seed: 0x6b8b4567
  exit=0

  # ./sev_migrate_tests; echo "exit=$?"
  Random seed: 0x6b8b4567
  exit=0

Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
---
 tools/testing/selftests/kvm/include/x86/sev.h | 12 +++++++
 tools/testing/selftests/kvm/lib/x86/sev.c     | 11 +++++--
 .../selftests/kvm/x86/sev_smoke_test.c        | 33 +++++++++++++++++--
 3 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h
index dec383e59a47..b29bf3aa0682 100644
--- a/tools/testing/selftests/kvm/include/x86/sev.h
+++ b/tools/testing/selftests/kvm/include/x86/sev.h
@@ -31,6 +31,18 @@ enum sev_guest_state {
 
 #define GHCB_MSR_TERM_REQ	0x100
 
+/*
+ * Layout of the blob returned by KVM_SEV_LAUNCH_MEASURE, per the SEV API
+ * specification, section 6.5.2: a measurement (HMAC-SHA256) followed by the
+ * nonce used to derive it.  Deriving the buffer and field sizes from this
+ * struct keeps callers layout-agnostic; only this definition needs to change
+ * if the measurement ABI is ever extended.
+ */
+struct sev_launch_measure_blob {
+	u8 measurement[32];
+	u8 mnonce[16];
+};
+
 static inline bool is_sev_snp_vm(struct kvm_vm *vm)
 {
 	return vm->type == KVM_X86_SNP_VM;
diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c
index 93f916903461..4bfb97a0364f 100644
--- a/tools/testing/selftests/kvm/lib/x86/sev.c
+++ b/tools/testing/selftests/kvm/lib/x86/sev.c
@@ -108,10 +108,17 @@ void sev_vm_launch_measure(struct kvm_vm *vm, u8 *measurement)
 	struct kvm_sev_launch_measure launch_measure;
 	struct kvm_sev_guest_status guest_status;
 
-	launch_measure.len = 256;
+	launch_measure.len = sizeof(struct sev_launch_measure_blob);
 	launch_measure.uaddr = (__u64)measurement;
 	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_MEASURE, &launch_measure);
 
+	/*
+	 * '.len' is an in/out field; the firmware reports back the actual size
+	 * of the measurement blob, which must match the layout described by
+	 * struct sev_launch_measure_blob.
+	 */
+	TEST_ASSERT_EQ(launch_measure.len, sizeof(struct sev_launch_measure_blob));
+
 	vm_sev_ioctl(vm, KVM_SEV_GUEST_STATUS, &guest_status);
 	TEST_ASSERT_EQ(guest_status.state, SEV_GUEST_STATE_LAUNCH_SECRET);
 }
@@ -191,7 +198,7 @@ void vm_sev_launch(struct kvm_vm *vm, u64 policy, u8 *measurement)
 	sev_vm_launch(vm, policy);
 
 	if (!measurement)
-		measurement = alloca(256);
+		measurement = alloca(sizeof(struct sev_launch_measure_blob));
 
 	sev_vm_launch_measure(vm, measurement);
 
diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
index bf27b6187afa..51adf7a1e1b6 100644
--- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
@@ -150,16 +150,45 @@ static void test_sync_vmsa(u32 type, u64 policy)
 	kvm_vm_free(vm);
 }
 
+static bool is_range_nonzero(const u8 *buf, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		if (buf[i])
+			return true;
+
+	return false;
+}
+
 static void test_sev(void *guest_code, u32 type, u64 policy)
 {
+	struct sev_launch_measure_blob blob;
 	struct kvm_vcpu *vcpu;
 	struct kvm_vm *vm;
 	struct ucall uc;
 
 	vm = vm_sev_create_with_one_vcpu(type, guest_code, &vcpu);
 
-	/* TODO: Validate the measurement is as expected. */
-	vm_sev_launch(vm, policy, NULL);
+	/*
+	 * Capture and sanity check the launch measurement.  A full
+	 * attestation-style validation (recomputing the expected value) isn't
+	 * possible here as userspace does not possess the transport keys the
+	 * PSP uses to derive the measurement.  At minimum, the firmware must
+	 * hand back a non-zero measurement and a non-zero nonce (the blob
+	 * length is validated by vm_sev_launch()).  SNP does not return a
+	 * measurement through this path, so skip it.
+	 */
+	if (is_sev_snp_vm(vm)) {
+		vm_sev_launch(vm, policy, NULL);
+	} else {
+		memset(&blob, 0, sizeof(blob));
+		vm_sev_launch(vm, policy, (u8 *)&blob);
+		TEST_ASSERT(is_range_nonzero(blob.measurement, sizeof(blob.measurement)),
+			    "SEV launch measurement is unexpectedly all zeros");
+		TEST_ASSERT(is_range_nonzero(blob.mnonce, sizeof(blob.mnonce)),
+			    "SEV launch measurement nonce is unexpectedly all zeros");
+	}
 
 	for (;;) {
 		vcpu_run(vcpu);
-- 
2.43.7


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 1/1] KVM: selftests: SEV: Sanity check the launch measurement
  2026-08-11  4:08 ` [PATCH v2 1/1] " Hemanth Selam
@ 2026-08-26  5:04   ` Hemanth Selam
  0 siblings, 0 replies; 3+ messages in thread
From: Hemanth Selam @ 2026-08-26  5:04 UTC (permalink / raw)
  To: seanjc, pbonzini, shuah; +Cc: kvm, linux-kselftest, linux-kernel

Gentle ping on this one, no rush - I realise this landed in the quiet part
of the cycle.

The TODO it addresses is still present in sev_smoke_test.c:

  /* TODO: Validate the measurement is as expected. */

and the patch still applies cleanly to kvm-x86/next.

Happy to rebase or rework it if you would rather see it done differently,
and equally happy to drop it if you decided against this approach.

Thanks,
Hemanth

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-26  5:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11  4:08 [PATCH v2 0/1] KVM: selftests: SEV: Sanity check the launch measurement Hemanth Selam
2026-08-11  4:08 ` [PATCH v2 1/1] " Hemanth Selam
2026-08-26  5:04   ` Hemanth Selam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox