From 423778aec7673ecdc3ecae867be1a8faa3e6816e Mon Sep 17 00:00:00 2001 From: Dov Murik Date: Thu, 6 Oct 2022 14:46:37 +0300 Subject: [PATCH] runtime: sev: Add unittests; allow measurement without kernel 1. Add unit tests for pkg/sev 2. Allow CalculateLaunchDigest to calculate launch digest without direct booted kernel (and, therefore, without initrd and kernel cmdline). This mode is currently not used in kata. Fixes: #5456 Signed-off-by: Dov Murik --- src/runtime/pkg/README.md | 1 + src/runtime/pkg/sev/README.md | 14 ++++++++ src/runtime/pkg/sev/sev.go | 10 +++--- src/runtime/pkg/sev/sev_test.go | 32 +++++++++++++++++++ src/runtime/pkg/sev/testdata/README.md | 9 ++++++ src/runtime/pkg/sev/testdata/ovmf_suffix.bin | Bin 0 -> 4096 bytes 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 src/runtime/pkg/sev/README.md create mode 100644 src/runtime/pkg/sev/sev_test.go create mode 100644 src/runtime/pkg/sev/testdata/README.md create mode 100644 src/runtime/pkg/sev/testdata/ovmf_suffix.bin diff --git a/src/runtime/pkg/README.md b/src/runtime/pkg/README.md index b5b0d07d32..72bf3248bb 100644 --- a/src/runtime/pkg/README.md +++ b/src/runtime/pkg/README.md @@ -7,4 +7,5 @@ This repository contains a number of packages in addition to the |-|-| | [`katatestutils`](katatestutils) | Unit test utilities. | | [`katautils`](katautils) | Utilities. | +| [`sev`](sev) | AMD SEV confidential guest utilities. | | [`signals`](signals) | Signal handling functions. | diff --git a/src/runtime/pkg/sev/README.md b/src/runtime/pkg/sev/README.md new file mode 100644 index 0000000000..8e864f46fa --- /dev/null +++ b/src/runtime/pkg/sev/README.md @@ -0,0 +1,14 @@ +# AMD SEV confidential guest utilities + +This package provides utilities for launching AMD SEV confidential guests. + +## Calculating expected launch digests + +The `CalculateLaunchDigest` function can be used to calculate the expected +SHA-256 of an SEV confidential guest given its firmware, kernel, initrd, and +kernel command-line. + +### Unit test data + +The [`testdata`](testdata) directory contains file used for testing +`CalculateLaunchDigest`. diff --git a/src/runtime/pkg/sev/sev.go b/src/runtime/pkg/sev/sev.go index d95d2012b6..0b84abaa97 100644 --- a/src/runtime/pkg/sev/sev.go +++ b/src/runtime/pkg/sev/sev.go @@ -152,11 +152,13 @@ func CalculateLaunchDigest(firmwarePath, kernelPath, initrdPath, cmdline string) return res, err } - ht, err := constructSevHashesTable(kernelPath, initrdPath, cmdline) - if err != nil { - return res, err + if kernelPath != "" { + ht, err := constructSevHashesTable(kernelPath, initrdPath, cmdline) + if err != nil { + return res, err + } + digest.Write(ht) } - digest.Write(ht) copy(res[:], digest.Sum(nil)) return res, nil diff --git a/src/runtime/pkg/sev/sev_test.go b/src/runtime/pkg/sev/sev_test.go new file mode 100644 index 0000000000..d1ffffa7ff --- /dev/null +++ b/src/runtime/pkg/sev/sev_test.go @@ -0,0 +1,32 @@ +// Copyright contributors to AMD SEV/-ES in Go +// +// SPDX-License-Identifier: Apache-2.0 + +package sev + +import ( + "encoding/hex" + "testing" +) + +func TestCalculateLaunchDigestWithoutKernelHashes(t *testing.T) { + ld, err := CalculateLaunchDigest("testdata/ovmf_suffix.bin", "", "", "") + if err != nil { + t.Fatalf("unexpected err value: %s", err) + } + hexld := hex.EncodeToString(ld[:]) + if hexld != "b184e06e012366fd7b33ebfb361a515d05f00d354dca07b36abbc1e1e177ced5" { + t.Fatalf("wrong measurement: %s", hexld) + } +} + +func TestCalculateLaunchDigestWithKernelHashes(t *testing.T) { + ld, err := CalculateLaunchDigest("testdata/ovmf_suffix.bin", "/dev/null", "/dev/null", "") + if err != nil { + t.Fatalf("unexpected err value: %s", err) + } + hexld := hex.EncodeToString(ld[:]) + if hexld != "d59d7696efd7facfaa653758586e6120c4b6eaec3e327771d278cc6a44786ba5" { + t.Fatalf("wrong measurement: %s", hexld) + } +} diff --git a/src/runtime/pkg/sev/testdata/README.md b/src/runtime/pkg/sev/testdata/README.md new file mode 100644 index 0000000000..34554dc8e2 --- /dev/null +++ b/src/runtime/pkg/sev/testdata/README.md @@ -0,0 +1,9 @@ +# sev/testdata + +The `ovmf_suffix.bin` contains the last 4KB of the `OVMF.fd` binary from edk2's +`OvmfPkg/AmdSev/AmdSevX64.dsc` build. To save space, we committed only the +last 4KB instead of the the full 4MB binary. + +The end of the file contains a GUIDed footer table with entries that hold the +SEV-ES AP reset vector address, which is needed in order to compute VMSAs for +SEV-ES guests. diff --git a/src/runtime/pkg/sev/testdata/ovmf_suffix.bin b/src/runtime/pkg/sev/testdata/ovmf_suffix.bin new file mode 100644 index 0000000000000000000000000000000000000000..cc6d7ca7f0873de1305bfef33a7c1814934d8cf4 GIT binary patch literal 4096 zcmeGee{2(F^j&)`9Tu+64hk!*gAx%lTp?}bV<;`>U?XDi* z)8t^ggXLEKB1Q`tU$8$=F;?gO&hN|Ab4F!+K;n#It8&sMi7kO1PR9<(qw!okkb@ z3#KbMC={DKd|}mUZmfQRNsy*9M;|lZ)2f~34=dZ3zBI4r z{YrOL*%?%$@Mk3Y#ps(f7h$VPNDbGJl#YfH9gtFT4ZlT})&<~iv(n$-r;!i+Da4Ti z|B#1om+Mk$x9n;86DiiPy_`)0FpdOstjoYmNw_-Xw+tlN+`K3nNX#r0n3#N5N0da& z92`TVBWyMk|GjoV9Aid;iT{CUmIcw{nvO$4n;d3})P1Q>Rc#RHU^5HM(}*sYRbZV) zG&wV0)Psp8J4+|8DTDG1OlO3+9ZOioz@1o0ZP9#+l9>Ff40Z0Ba@}79Xi0G^Z*`^C z9mN13GS%+~kv;_uKSTjf5nIb+2{VS`2SIugC4Jjb!Fp;CL1$+)18w5;DH^TFl8<6O zTy4WQ7=u|hyh^qsH%i(iLZWWLNA6613a|qry9ZQtCPUds$@rOuq8tQu&qN4d8kl1V zs&-w}MV!a{C7^aii$U}KAUQ|OGU0wxS6@5krY=IsbkOaz2PZ)S6K26JPCJQV-0h^( zkQ6PUaby4p1HkN*5GkNIqp*br*0@-Rk7Dl<`gF|BeV7PY9#mEN zYuut>!?uw``sG1&J9PHOwSJpwAvI0|)|3GdpX$(P#Nq}Mq4NoC)@Tc%iwSMjXd9s` z2yI6!3Rr_$CubQh;mxFtb5MwFjG*(fEaQvGKcWQt5GT=;cG-m-ZH_Yy{J_GR%^X+7 zCpT=aS;Q^l`!};So47KqEtrPh7~1*SxoK^oFSqXANG|fC_yc0T2=%$~d~#EzyP9M8 zeg`gYlxD8zT#}+wUc;}FLl^?~4u278ZD4y9ORCp(q>U$$PFI}CNc)hgGL)tJPpnQ0 zcp@eUwTGloBGeT+gXdgOj>y@VXqS{4K|0RlYO5zF7R%ewbeKD;#Xy*pY}OiPm~GH} zlFO2*`Ym~+v}y^)fCmD;2rfUCbc%+0#Piem8N~6q$pnTkUYN4uxH5#6#tq!_0*emDLWkvn`hBv2uYx2Bfn*{i2Pg9nD;2WfgQ zG(J?JjBYHcPz)aN1ZJdP38eA}ia|b)N69ODaeI?&<^A}^m;kjrx1~I{xjgqoxtLIY z)|z(sz6z|IaWJRm`JW!%zklJ2>&gO$8bhDIhbb8co|;|f3HQ*tRmgqnD;V?x&;S!5 zXYML*;e2}WD=$oX`?tg2RKgXM;QX5i>pz~kJ_<