Merge pull request #5927 from dubek/sev-es-guest

CCv0: runtime: Support launching SEV-ES guests
This commit is contained in:
Steve Horsman 2023-01-04 09:37:27 +00:00 committed by GitHub
commit de999429ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 2 deletions

View File

@ -46,3 +46,31 @@ const (
// 'EPYC-Milan-v2': family=25, model=1, stepping=1
SigEpycMilanV2 VCPUSig = 0xa00f11
)
// NewVCPUSig computes the CPU signature (32-bit value) from the given family,
// model, and stepping.
//
// This computation is described in AMD's CPUID Specification, publication #25481
// https://www.amd.com/system/files/TechDocs/25481.pdf
// See section: CPUID Fn0000_0001_EAX Family, Model, Stepping Identifiers
func NewVCPUSig(family, model, stepping uint32) VCPUSig {
var family_low, family_high uint32
if family > 0xf {
family_low = 0xf
family_high = (family - 0x0f) & 0xff
} else {
family_low = family
family_high = 0
}
model_low := model & 0xf
model_high := (model >> 4) & 0xf
stepping_low := stepping & 0xf
return VCPUSig((family_high << 20) |
(model_high << 16) |
(family_low << 8) |
(model_low << 4) |
stepping_low)
}

View File

@ -0,0 +1,21 @@
// Copyright contributors to AMD SEV/-ES in Go
//
// SPDX-License-Identifier: Apache-2.0
package sev
import (
"testing"
)
func TestNewVCPUSig(t *testing.T) {
if NewVCPUSig(23, 1, 2) != SigEpyc {
t.Errorf("wrong EPYC CPU signature")
}
if NewVCPUSig(23, 49, 0) != SigEpycRome {
t.Errorf("wrong EPYC-Rome CPU signature")
}
if NewVCPUSig(25, 1, 1) != SigEpycMilan {
t.Errorf("wrong EPYC-Milan CPU signature")
}
}

View File

@ -9,6 +9,7 @@ package virtcontainers
import (
"context"
"crypto/sha256"
b64 "encoding/base64"
"fmt"
"log"
@ -38,6 +39,8 @@ type qemuAmd64 struct {
devLoadersCount uint32
sgxEPCSize int64
numVCPUs uint32
}
const (
@ -58,6 +61,9 @@ const (
sevAttestationGodhName = "godh.b64"
sevAttestationSessionFileName = "session_file.b64"
// For more info, see AMD SEV API document 55766
sevPolicyBitSevEs = 0x4
)
var kernelParams = []Param{
@ -140,6 +146,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
},
vmFactory: factory,
snpGuest: config.SevSnpGuest,
numVCPUs: config.NumVCPUs,
}
if config.ConfidentialGuest {
@ -409,6 +416,34 @@ func (q *qemuAmd64) setupSEVGuestPreAttestation(ctx context.Context, config sev.
return attestationId, nil
}
func getCPUSig(cpuModel string) sev.VCPUSig {
// This is for the special case for SNP (see cpuModel()).
if cpuModel == "EPYC-v4" {
return sev.SigEpycV4
}
return sev.NewVCPUSig(cpuid.DisplayFamily, cpuid.DisplayModel, cpuid.SteppingId)
}
func calculateGuestLaunchDigest(config sev.GuestPreAttestationConfig, numVCPUs int, cpuModel string) ([sha256.Size]byte, error) {
if config.Policy&sevPolicyBitSevEs != 0 {
// SEV-ES guest
return sev.CalculateSEVESLaunchDigest(
numVCPUs,
getCPUSig(cpuModel),
config.FwPath,
config.KernelPath,
config.InitrdPath,
config.KernelParameters)
}
// SEV guest
return sev.CalculateLaunchDigest(
config.FwPath,
config.KernelPath,
config.InitrdPath,
config.KernelParameters)
}
// wait for prelaunch attestation to complete
func (q *qemuAmd64) sevGuestPreAttestation(ctx context.Context,
qmp *govmmQemu.QMP, config sev.GuestPreAttestationConfig) error {
@ -447,9 +482,9 @@ func (q *qemuAmd64) sevGuestPreAttestation(ctx context.Context,
secrets := []*pb.RequestDetails{&requestDetails}
launchDigest, err := sev.CalculateLaunchDigest(config.FwPath, config.KernelPath, config.InitrdPath, config.KernelParameters)
launchDigest, err := calculateGuestLaunchDigest(config, int(q.numVCPUs), q.cpuModel())
if err != nil {
return fmt.Errorf("Could not calculate SEV launch digest: %v", err)
return fmt.Errorf("Could not calculate SEV/SEV-ES launch digest: %v", err)
}
launchDigestBase64 := b64.StdEncoding.EncodeToString(launchDigest[:])