Skip to content

attest: add attestation testing with kbs-test integration#1002

Open
nihalxkumar wants to merge 3 commits into
coconut-svsm:mainfrom
nihalxkumar:improve-attestation-tests-kbs
Open

attest: add attestation testing with kbs-test integration#1002
nihalxkumar wants to merge 3 commits into
coconut-svsm:mainfrom
nihalxkumar:improve-attestation-tests-kbs

Conversation

@nihalxkumar

@nihalxkumar nihalxkumar commented Mar 15, 2026

Copy link
Copy Markdown
Contributor
This PR adds tests for both attestation surfaces.

SVSM exposes two distinct attestation surfaces: the pre-boot attestation feature (the attest Rust feature flag), which runs before the guest OS starts and uses a KBS to retrieve secrets, and the in-guest attestation
protocol, through which a VMPL0 guest can request a hardware attestation
report via SVSM.

For the in-guest attestation protocol the wire format of AttestServicesOp and AttestSingleServiceOp is fixed by the SVSM spec (Tables 11 and 13 of "Secure VM Service Module for SEV-SNP Guests, Rev 1.00"). A silent field reorder or padding change would break the binary interface with the guest, so the layout is now enforced with compile-time const assertions, following the pattern established in greq/msg.rs. Runtime tests cover reserved-field rejection, certificate region boundary enforcement, GUID table serialization, and that unknown request codes return UNSUPPORTED_PROTOCOL.

For pre-boot attestation, the hash() function feeds NegotiationParams into SHA-512 in the order dictated by the
server's NegotiationResponse. Because the server controls which params contribute and in what sequence, ordering sensitivity is a security property.
Tests verify that Challenge → EcPublicKeyBytes and EcPublicKeyBytes → Challenge produce the expected individual digests and that swapping the order produces a distinct output.

The third commit adds a test script that exercises the pre-boot KBS flow end-to-end: it starts kbs-test and
aproxy, launches the SVSM test image built with the attest feature, and checks that "attestation successful" appears in the output. This requires a real SNP-capable machine and is not wired into the standard QEMU CI
workflow for that reason.

Related: #773

@nhandt64

Copy link
Copy Markdown
Contributor

Thanks for 67351f9! That comes in really handy.

Comment thread Makefile Outdated
Comment thread configs/test/qemu-test-attest-target.json Outdated
Comment thread scripts/test-qemu-nocc-svsm-attest.sh Outdated
Comment thread Documentation/docs/installation/INSTALL.md
@osteffenrh

Copy link
Copy Markdown
Collaborator

This commit "scripts: fix bash array expansion and update license" can be squashed, right? Please do that.

@luigix25

Copy link
Copy Markdown
Collaborator

sorry, but I'm a little bit confused. How do you run attestation testing in the CI/no-cc mode without snp hardware?

Comment thread kernel/src/protocols/attest.rs Outdated
Comment thread kernel/src/protocols/attest.rs Outdated
@nihalxkumar nihalxkumar force-pushed the improve-attestation-tests-kbs branch from ef1af17 to 69a3f87 Compare March 18, 2026 13:10
@nihalxkumar nihalxkumar requested a review from osteffenrh March 18, 2026 13:48

@luigix25 luigix25 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real attestation cannot be performed on a normal x86 machines, it requires an AMD SEV SNP capable machine.

This means that the nocc option does not make any sense. As a consequence the CI will fail, as it's running on a x86 machine.

That said, adding a fake attestation report, for testing purposes, could be a good idea.

I see that you added a lot of tests, most of them being extremely trivial, are they useful?

Also please avoid all unnecessary changes, like new blank-lines.

Sorry to say, but to me this PR looks like AI generated.

@nihalxkumar

Copy link
Copy Markdown
Contributor Author

@luigix25 Thanks for the feedback

I did take AI's help. I apologize if some of the tests ended up being too trivial. The extra blank lines in the Makefile definitely slipped past my review, sorry for the noise there.
Largely, I tried to address the original issue as much as I could understand.
If the overall approach is still valuable, I am more than happy to put in the time to improve this PR.

@luigix25

Copy link
Copy Markdown
Collaborator

@luigix25 Thanks for the feedback

I did take AI's help. I apologize if some of the tests ended up being too trivial. The extra blank lines in the Makefile definitely slipped past my review, sorry for the noise there. Largely, I tried to address the original issue as much as I could understand. If the overall approach is still valuable, I am more than happy to put in the time to improve this PR.

There is some value in this PR, having a script that sets up all the attestation pieces IMO is useful.

CI part can be dropped entirely. It would be useful is we could do some sort of "emulated" attestation, but we don't have it yet as the SVSM kernel would require some changes, but it's not a small task.

Having unit tests for attestation would be great, but please review them carefully and leave only those that make non-trivial checks. It's important to explain the reason behind any test.

I think there is also some overlap in the documentation.

So, before submitting a new version, please review your PR carefully. Make sure that all the changes are intended and documented. Commit message should explain why you are doing something, it's (often) easy to understand what you are doing. Hope this can help you: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes

@nihalxkumar nihalxkumar requested a review from luigix25 March 20, 2026 11:49
@nihalxkumar

Copy link
Copy Markdown
Contributor Author

The kernel docs were very helpful. Please check and suggest any changes.

Comment thread .github/workflows/qemu.yml Outdated
Comment thread .github/workflows/qemu.yml Outdated
Comment thread .github/workflows/qemu.yml
Comment thread .github/workflows/qemu.yml Outdated
Add a dedicated attestation launcher that starts kbs-test and aproxy
and runs the test IGVM with attestation enabled.

Reuse the existing test-in-svsm target for this flow by selecting the
launcher and extra dependencies through make variables, and document the
manual invocation in TESTING.md. The attestation runner rejects --nocc

Signed-off-by: Nihal <nihalxkumar@protonmail.com>
@nihalxkumar nihalxkumar force-pushed the improve-attestation-tests-kbs branch from a4e6458 to 0d99da3 Compare March 23, 2026 16:41
@nihalxkumar

Copy link
Copy Markdown
Contributor Author

Changes as asked by @luigix25
// For reference: 18 March patch and 20 March patch

@stefano-garzarella

Copy link
Copy Markdown
Member

@nihalxkumar please resolve all the conversations that you addressed. Only the PR author and maintainer can do that, so it's a good practice for the PR author to close them (if addressed of course).

@stefano-garzarella

Copy link
Copy Markdown
Member

Integration testing:

* Make TEST_IGVM overridable in test-in-svsm.sh so it can be reused for attestation runs.

* Add a new IGVM config (qemu-test-attest-target.json) and Makefile target (test-in-svsm-attest) that builds with vtpm,virtio-drivers,block,attest features.

Where is this? and also why?

* Add test-in-svsm-attest.sh: start kbs-test → start aproxy → run in-SVSM tests → verify "attestation successful" appears in output. Logs from all components are dumped on failure.

Ditto, I'm really really confused.

Please update the PR description, but don't do a list of things, you should describe the goal of this PR, what is adding/fixing, and the reason of some choice.

Closes: #773

I don't think this PR is related to that. I can't see any test stressing the KBS protocol, aproxy, etc.

Maybe that issue was not clear, but in SVSM we have:

  1. pre-boot attestation feature (controlled by attest rust feature) used with KBS to receive back a secret (e.g. it will be used to unlock the encrypted persistent storage)
  2. attestation protocol used by the guest to have a VMPL0 attestation report

That issue is more for 1, since we are adding more tests for the attestation protocol. I see something also for pre-boot attestation, but again I don't understand how aproxy, kbs-test are used by those tests, can you explain that, even in the commit description?

And please split the tests at least in 2 commits: one for pre-boot attestation (kernel/src/attest.rs) and one for attestation protocol (kernel/src/protocols/attest.rs).

Comment thread kernel/src/protocols/attest.rs Outdated
Add unit tests for the hash() function used during pre-boot attestation
negotiation.

hash() feeds NegotiationParams into SHA-512 in the order dictated by
the server's NegotiationResponse. Because the server controls which
params contribute and in what sequence, ordering sensitivity is a
security property: different orderings must produce different digests.

Tests cover:
- Challenge-first and EcPublicKeyBytes-first orderings, verified
  against a manually computed SHA-512 reference.
- That swapping the param order produces a distinct digest.

Signed-off-by: Nihal <nihalxkumar@protonmail.com>
Add unit tests for the attestation protocol request handler
(kernel/src/protocols/attest.rs).

The SVSM attestation protocol exposes a fixed wire ABI defined by
Table 11 and Table 13 of "Secure VM Service Module for SEV-SNP Guests,
Rev 1.00". Any accidental field reordering or padding change would
silently break the guest interface, so the layout of AttestServicesOp
and AttestSingleServiceOp is now checked with compile-time
const assertions (following the pattern in greq/msg.rs).

Runtime tests cover:
- Reserved-field validation: every reserved region in both structs must
  be rejected when non-zero, guarding forward-compatibility with future
  spec revisions.
- Certificate region boundary: size==0 is valid (no extended report);
  size<=MAX_CERTIFICATE_SIZE is accepted; size>MAX_CERTIFICATE_SIZE is
  rejected.
- GUID serialization: single-entry and multi-entry GuidTable wire
  format, including offset arithmetic between header and payload.
- Protocol routing: unknown request codes must return
  UNSUPPORTED_PROTOCOL.

Signed-off-by: Nihal <nihalxkumar@protonmail.com>
@nihalxkumar nihalxkumar force-pushed the improve-attestation-tests-kbs branch from 0d99da3 to 198e38a Compare April 2, 2026 09:45
Comment on lines +74 to +75
Attestation can be tested in the same infrastructure by running the
attest-enabled test image together with `kbs-test` and `aproxy`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm still confused, why you need to run kbs-test and aproxy for the tests you added.

Can you tell me which of the tests we're adding require communication with KBS?
Maybe I missed something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the unit tests in commits 2 and 3 require kbs-test or aproxy.

commit 1 (test-in-svsm-attest.sh) needs kbs-test and aproxy as it is an end-to-end integration test
that boots the SVSM test image on real SNP hardware with the attest feature enabled, connects it to a local kbs-test server via aproxy, and checks that pre-boot attestation completes successfully ("attestation successful" in output).

This is the part that addresses the kbs-test integration mentioned in the original issue.

The TESTING.md is documenting the integration script.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So commit 1 and commits 2/3 are completely unrelated, right?
Why putting them in a single PR ?

Comment thread Makefile
distclean: clean

.PHONY: test miri clean clippy bin/stage2.bin bin/svsm-kernel.elf bin/test-kernel.elf stage1_elf_trampoline distclean $(APROXYBIN) $(IGVM_FILES) $(IGVM_TEST_FILES)
.PHONY: test miri clean clippy bin/stage2.bin bin/svsm-kernel.elf bin/test-kernel.elf stage1_elf_full stage1_elf_trampoline stage1_elf_test distclean $(APROXYBIN) $(IGVM_FILES) $(IGVM_TEST_FILES) test-in-svsm

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why adding stage1_elf_full and stage1_elf_test ?

Comment thread Makefile
test-in-svsm: bin/coconut-test-qemu.igvm $(IGVMMEASUREBIN)
./scripts/test-in-svsm.sh $(TEST_ARGS)
test-in-svsm: $(IGVMMEASUREBIN) $(TEST_IN_SVSM_DEPS)
cargo xbuild $(XBUILD_ARGS_TEST) ./configs/test/qemu-test-target.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why removing the dep with bin/coconut-test-qemu.igvm and adding the step here to build it?

make FEATURES_TEST=vtpm,virtio-drivers,block,attest \
TEST_IN_SVSM_SCRIPT=./scripts/test-in-svsm-attest.sh \
TEST_IN_SVSM_DEPS=aproxy \
test-in-svsm

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't reuse test-in-svsm target that is used to run rust test in the SVSM context.
This new test is more like scripts/test-qemu-nocc-svsm.sh, so if you want to add a target in the makefile, just define a new one, or just document how to run the script directly.

Comment on lines +74 to +75
Attestation can be tested in the same infrastructure by running the
attest-enabled test image together with `kbs-test` and `aproxy`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So commit 1 and commits 2/3 are completely unrelated, right?
Why putting them in a single PR ?

Comment thread scripts/test-in-svsm.sh
set -e

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
: "${TEST_IGVM:=$SCRIPT_DIR/../bin/coconut-test-qemu.igvm}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this change is related?

Comment thread kernel/src/attest.rs
}

#[cfg(test)]
mod tests {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CC @tylerfanelli on these tests.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests LGTM.

stefano-garzarella added a commit to stefano-garzarella/svsm that referenced this pull request Apr 7, 2026
The SPDX and SignedOff workflows override the checkout ref to
`github.event.pull_request.head.sha`. This breaks PRs whose branches
were created before the scripts used by the pipelines were added to
main. For example the CI of PR coconut-svsm#1002 is failing to execute the SPDX
pipeline [1] with the following:

    scripts/check-spdx.sh: No such file or directory
    Process completed with exit code 127.

For `pull_request` events, GitHub runs workflows from a merge commit
of the PR head into the target branch [2]:

    "GITHUB_SHA for this event is the last merge commit on the
     pull request merge branch."

So the workflow file from main is picked up and executed, but the
checkout then switches to the PR head, where the scripts do not exist.

Drop the `ref:` override to let actions/checkout use its default, which
checks out the merge commit. Both the scripts (from main) and the PR
changes are available there. The SPDX script reads files from the
working tree and the SignedOff script only inspects git objects, so
both work correctly with the merge commit.

[1] https://github.com/coconut-svsm/svsm/actions/runs/23894438075/job/69675546900
[2] https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
@stefano-garzarella stefano-garzarella added the in-review PR is under active review and not yet approved label Apr 8, 2026
stefano-garzarella added a commit to stefano-garzarella/svsm that referenced this pull request Apr 8, 2026
The SPDX and SignedOff workflows before merging PR coconut-svsm#1032, and the new
PR Compliance Checks after the merge, override the checkout ref to
`github.event.pull_request.head.sha`. This breaks PRs whose branches
were created before the scripts used by the pipelines were added to main.
For example the CI of PR coconut-svsm#1002 is failing to execute the SPDX
pipeline [1] with the following:

    scripts/check-spdx.sh: No such file or directory
    Process completed with exit code 127.

For `pull_request` events, GitHub runs workflows from a merge commit
of the PR head into the target branch [2]:

    "GITHUB_SHA for this event is the last merge commit on the
     pull request merge branch."

So the workflow file from main is picked up and executed, but the
checkout then switches to the PR head, where the scripts do not exist.

Drop the `ref:` override to let actions/checkout use its default, which
checks out the merge commit. Both the scripts (from main) and the PR
changes are available there. The SPDX script reads files from the
working tree and the SignedOff script only inspects git objects, so
both work correctly with the merge commit.

[1] https://github.com/coconut-svsm/svsm/actions/runs/23894438075/job/69675546900
[2] https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
@stefano-garzarella stefano-garzarella added the wait-for-update PR is waiting to be updated to address review comments label Apr 9, 2026
@stefano-garzarella

Copy link
Copy Markdown
Member

@nihalxkumar are you still working on this, otherwise I'll fixup the remaining issues and try to merge it.

@nihalxkumar

nihalxkumar commented Jun 30, 2026 via email

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in-review PR is under active review and not yet approved wait-for-update PR is waiting to be updated to address review comments

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants