Skip to content

Add SNP kernel hash support#5073

Open
CookieComputing wants to merge 2 commits intoproject-oak:mainfrom
CookieComputing:add_kernel_hashes
Open

Add SNP kernel hash support#5073
CookieComputing wants to merge 2 commits intoproject-oak:mainfrom
CookieComputing:add_kernel_hashes

Conversation

@CookieComputing
Copy link
Contributor

At Meta, we've been using the kernel-hashes measurement feature provided in QEMU to cover the launch components of our CVMs. This is computed as part of the launch digest.

The reason you'd consider using this is because this will include the bootloader, initrd, kernel, and kernel cmdline into your launch digest, making these components attested. At least from Private Processing's point of view, we then allow the kernel to run dm-verity to do disk integrity checks to trust our rootfs.

We've been using some variant of this patch for a while in production now and wanted to share this with you if you wanted to support kernel hashes! I've modified the patch so that enabling this feature is optional, as I know this is not the intended DICE attestation method you folks use.

We base this implementation from the OVMF GUID table structure defined here and the layout of the OVMF binary here

Testing

All tests were done on our own servers, I'd recommend doing a positive/negative test with your own hypervisor just to double check that the change doesn't break the existing flow at Google (at the very least, I would expect that not including the feature should function as normal).

Tests were done on an AMD Bergamo host to ensure we had a v3 attestation report. I used basically vanilla QEMU 9.2 to run these jobs.

Positive test

I built stage0_bin on master and uncommented the sev_kernel_hashes features to enable the build. I then ran the following QEMU command (with paste here):

positive_case.txt

The most important parts to note in this invocation and log:

/usr/bin/qemu-system-x86_64 "-enable-kvm" ... "-object" "sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,policy=196608,id-block=...author-key-enabled=true,kernel-hashes=on,id-auth=...
stage0 INFO: starting...
...
stage0 DEBUG: validating measured boot primitives
stage0 DEBUG: validated measured boot primitives

This showcases that stage0 found the kernel hashes in the provided table, and then compared them to the fw_cfg components.

Negative test

I built stage0_bin on master with this diff, and did not do anything (i.e. did not uncomment the sev_kernel_hashes feature). I then ran the following QEMU command (with paste here):

negative_case.txt

Most important things to note:

/usr/bin/qemu-system-x86_64 "-enable-kvm" ... "-bios" "/tmp/stage0_bin_no_hashes" ...  "-object" "sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,author-key-enabled=false,kernel-hashes=off"
...
stage0 INFO: Entry WAET (0x3ff023a6-0x3ff023ce): DescriptionHeader { signature: [87, 65, 69, 84], length: 40, revision: 1, checksum: 57, oem_id: [66, 79, 67, 72, 83, 32], oem_table_id: [66, 88, 80, 67, 32, 32, 32, 32], oem_revision: 1, creator_id: 1129338946, creator_revision: 1 }
stage0 INFO: No XSDT present
stage0 DEBUG: Initial RAM disk size 29174433
stage0 DEBUG: Initial RAM disk address 0x000000003e32d000
stage0 DEBUG: Kernel image digest: sha2-256:c9cdd65c874c896d211cd85074182374c3588e778b84109fc551b77e75a302bb

The validation call in stage0/lib.rs is not invoked, so we do not see any logs w.r.t. kernel hashes

Matches sev-snp-measure launch digest

This attestation is only really useful if we check it against an open source tool. At Meta, we use the open source virTEE/sev-snp-measure tool, as this is widely accessible and AMD also makes updates to this tool whenever they make updates to firmware attestation

attestation_report.txt

The launch digest is:

Measurement:                  
4b d0 37 5f 41 b1 ff b4 0c bf ee 81 4f 71 84 f8 
4e 7a 1a 2d d7 62 6d 64 b0 7b 79 dd 95 4f d5 2c 
1f f4 c6 82 c8 f7 bb 13 70 3a ba 3b 1e 17 99 2c 

When running this against the sev-snp-measure tool, we see the following:

$ buck2 run //tee/snp/image:sev-snp-measure -- --vcpus 4 --vcpu-type EPYC-v4 --mode snp --ovmf /tmp/tmp.iXjDzansTZ//launch/stage0_bin --kernel /tmp/tmp.iXjDzansTZ/launch/cvm_vmlinuz --initrd /tmp/tmp.iXjDzansTZ/launch/layer.cpio.gz --append "audit=0 biosdevname=0 net.ifnames=0 console=ttyS0"
4bd0375f41b1ffb40cbfee814f7184f84e7a1a2dd7626d64b07b79dd954fd52c1ff4c682c8f7bb13703aba3b1e17992c

Upon visual inspection, we can see that these two measurements match up

This allows users to supply kernel hashes which contain
hashes of the kernel, kernel cmdline, initrd, and bootloader
provided to the guest at CVM launch time. These changes
are reflected in the launch digest of the CVM.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant