diff --git a/src/runtime/config/configuration-qemu-nvidia-gpu-snp.toml.in b/src/runtime/config/configuration-qemu-nvidia-gpu-snp.toml.in index 223f7f9186..8501ffbd0e 100644 --- a/src/runtime/config/configuration-qemu-nvidia-gpu-snp.toml.in +++ b/src/runtime/config/configuration-qemu-nvidia-gpu-snp.toml.in @@ -60,6 +60,18 @@ enable_annotations = @DEFENABLEANNOTATIONS@ # Your distribution recommends: @QEMUVALIDHYPERVISORPATHS@ valid_hypervisor_paths = @QEMUSNPVALIDHYPERVISORPATHS@ +# SNP 'ID Block' and 'ID Authentication Information Structure'. +# If one of snp_id_block or snp_id_auth is specified, the other must be specified, too. +# Notice that the default SNP policy of QEMU (0x30000) is used by Kata, and the IDBlock +# must be generated with exactly this policy. +# +# 96-byte, base64-encoded blob to provide the ‘ID Block’ structure for the +# SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (QEMU default: all-zero) +#snp_id_block = "" +# 4096-byte, base64-encoded blob to provide the ‘ID Authentication Information Structure’ +# for the SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (QEMU default: all-zero) +#snp_id_auth = "" + # Optional space-separated list of options to pass to the guest kernel. # For example, use `kernel_params = "vsyscall=emulate"` if you are having # trouble running pre-2.15 glibc. diff --git a/src/runtime/config/configuration-qemu-snp.toml.in b/src/runtime/config/configuration-qemu-snp.toml.in index 46c537971a..dcfb809440 100644 --- a/src/runtime/config/configuration-qemu-snp.toml.in +++ b/src/runtime/config/configuration-qemu-snp.toml.in @@ -60,6 +60,18 @@ enable_annotations = @DEFENABLEANNOTATIONS@ # Your distribution recommends: @QEMUVALIDHYPERVISORPATHS@ valid_hypervisor_paths = @QEMUVALIDHYPERVISORPATHS@ +# SNP 'ID Block' and 'ID Authentication Information Structure'. +# If one of snp_id_block or snp_id_auth is specified, the other must be specified, too. +# Notice that the default SNP policy of QEMU (0x30000) is used by Kata, and the IDBlock +# must be generated with exactly this policy. +# +# 96-byte, base64-encoded blob to provide the ‘ID Block’ structure for the +# SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (QEMU default: all-zero) +#snp_id_block = "" +# 4096-byte, base64-encoded blob to provide the ‘ID Authentication Information Structure’ +# for the SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (QEMU default: all-zero) +#snp_id_auth = "" + # Optional space-separated list of options to pass to the guest kernel. # For example, use `kernel_params = "vsyscall=emulate"` if you are having # trouble running pre-2.15 glibc. diff --git a/src/runtime/pkg/govmm/qemu/qemu.go b/src/runtime/pkg/govmm/qemu/qemu.go index 28b129921a..4ff4333f8c 100644 --- a/src/runtime/pkg/govmm/qemu/qemu.go +++ b/src/runtime/pkg/govmm/qemu/qemu.go @@ -318,6 +318,14 @@ type Object struct { // QgsPort defines Intel Quote Generation Service port exposed from the host QgsPort uint32 + + // SnpIdBlock is the 96-byte, base64-encoded blob to provide the ‘ID Block’ structure + // for the SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (default: all-zero) + SnpIdBlock string + + // SnpIdAuth is the 4096-byte, base64-encoded blob to provide the ‘ID Authentication Information Structure’ + // for the SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (default: all-zero) + SnpIdAuth string } // Valid returns true if the Object structure is valid and complete. @@ -389,6 +397,12 @@ func (object Object) QemuParams(config *Config) []string { objectParams = append(objectParams, fmt.Sprintf("cbitpos=%d", object.CBitPos)) objectParams = append(objectParams, fmt.Sprintf("reduced-phys-bits=%d", object.ReducedPhysBits)) objectParams = append(objectParams, "kernel-hashes=on") + if object.SnpIdBlock != "" { + objectParams = append(objectParams, fmt.Sprintf("id-block=%s", object.SnpIdBlock)) + } + if object.SnpIdAuth != "" { + objectParams = append(objectParams, fmt.Sprintf("id-auth=%s", object.SnpIdAuth)) + } config.Bios = object.File case SecExecGuest: objectParams = append(objectParams, string(object.Type)) diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go index b2590c88e6..79665e2593 100644 --- a/src/runtime/pkg/katautils/config.go +++ b/src/runtime/pkg/katautils/config.go @@ -107,6 +107,8 @@ type hypervisor struct { SeccompSandbox string `toml:"seccompsandbox"` BlockDeviceAIO string `toml:"block_device_aio"` RemoteHypervisorSocket string `toml:"remote_hypervisor_socket"` + SnpIdBlock string `toml:"snp_id_block"` + SnpIdAuth string `toml:"snp_id_auth"` HypervisorPathList []string `toml:"valid_hypervisor_paths"` JailerPathList []string `toml:"valid_jailer_paths"` VirtioFSDaemonList []string `toml:"valid_virtio_fs_daemon_paths"` @@ -986,6 +988,8 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { DisableSeLinux: h.DisableSeLinux, DisableGuestSeLinux: h.DisableGuestSeLinux, ExtraMonitorSocket: extraMonitorSocket, + SnpIdBlock: h.SnpIdBlock, + SnpIdAuth: h.SnpIdAuth, }, nil } diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go index 8297301645..b6b75d5499 100644 --- a/src/runtime/virtcontainers/hypervisor.go +++ b/src/runtime/virtcontainers/hypervisor.go @@ -461,6 +461,14 @@ type HypervisorConfig struct { // The user maps to the uid. User string + // SnpIdBlock is the 96-byte, base64-encoded blob to provide the ‘ID Block’ structure + // for the SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (default: all-zero) + SnpIdBlock string + + // SnpIdAuth is the 4096-byte, base64-encoded blob to provide the ‘ID Authentication Information Structure’ + // for the SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI (default: all-zero) + SnpIdAuth string + // KernelParams are additional guest kernel parameters. KernelParams []Param diff --git a/src/runtime/virtcontainers/qemu_amd64.go b/src/runtime/virtcontainers/qemu_amd64.go index ade7356eb6..dd0a929df0 100644 --- a/src/runtime/virtcontainers/qemu_amd64.go +++ b/src/runtime/virtcontainers/qemu_amd64.go @@ -13,6 +13,7 @@ import ( "time" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/intel-go/cpuid" @@ -33,6 +34,10 @@ type qemuAmd64 struct { sgxEPCSize int64 qgsPort uint32 + + snpIdBlock string + + snpIdAuth string } const ( @@ -125,9 +130,11 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) { protection: noneProtection, legacySerial: config.LegacySerial, }, - vmFactory: factory, - snpGuest: config.SevSnpGuest, - qgsPort: config.QgsPort, + vmFactory: factory, + snpGuest: config.SevSnpGuest, + qgsPort: config.QgsPort, + snpIdBlock: config.SnpIdBlock, + snpIdAuth: config.SnpIdAuth, } if config.ConfidentialGuest { @@ -233,7 +240,8 @@ func (q *qemuAmd64) enableProtection() error { "machine": q.qemuMachine, "kernel-params-debug": q.kernelParamsDebug, "kernel-params-non-debug": q.kernelParamsNonDebug, - "kernel-params": q.kernelParams}) + "kernel-params": q.kernelParams, + }) switch q.protection { case tdxProtection: @@ -303,15 +311,23 @@ func (q *qemuAmd64) appendProtectionDevice(devices []govmmQemu.Device, firmware, ReducedPhysBits: 1, }), "", nil case snpProtection: - return append(devices, - govmmQemu.Object{ - Type: govmmQemu.SNPGuest, - ID: "snp", - Debug: false, - File: firmware, - CBitPos: cpuid.AMDMemEncrypt.CBitPosition, - ReducedPhysBits: 1, - }), "", nil + obj := govmmQemu.Object{ + Type: govmmQemu.SNPGuest, + ID: "snp", + Debug: false, + File: firmware, + CBitPos: cpuid.AMDMemEncrypt.CBitPosition, + ReducedPhysBits: 1, + } + if q.snpIdBlock != "" && q.snpIdAuth != "" { + obj.SnpIdBlock = q.snpIdBlock + obj.SnpIdAuth = q.snpIdAuth + } else if q.snpIdBlock != "" { + return nil, "", errors.New("specifying SNP IDBlock without SNP IDAuth is not allowed") + } else if q.snpIdAuth != "" { + return nil, "", errors.New("specifying SNP IDAuth without SNP IDBlock is not allowed") + } + return append(devices, obj), "", nil case noneProtection: return devices, firmware, nil