mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-15 06:34:03 +00:00
Merge pull request #5927 from dubek/sev-es-guest
CCv0: runtime: Support launching SEV-ES guests
This commit is contained in:
commit
de999429ce
@ -46,3 +46,31 @@ const (
|
|||||||
// 'EPYC-Milan-v2': family=25, model=1, stepping=1
|
// 'EPYC-Milan-v2': family=25, model=1, stepping=1
|
||||||
SigEpycMilanV2 VCPUSig = 0xa00f11
|
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)
|
||||||
|
}
|
||||||
|
21
src/runtime/pkg/sev/vcpu_sigs_test.go
Normal file
21
src/runtime/pkg/sev/vcpu_sigs_test.go
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ package virtcontainers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
b64 "encoding/base64"
|
b64 "encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@ -38,6 +39,8 @@ type qemuAmd64 struct {
|
|||||||
devLoadersCount uint32
|
devLoadersCount uint32
|
||||||
|
|
||||||
sgxEPCSize int64
|
sgxEPCSize int64
|
||||||
|
|
||||||
|
numVCPUs uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -58,6 +61,9 @@ const (
|
|||||||
sevAttestationGodhName = "godh.b64"
|
sevAttestationGodhName = "godh.b64"
|
||||||
|
|
||||||
sevAttestationSessionFileName = "session_file.b64"
|
sevAttestationSessionFileName = "session_file.b64"
|
||||||
|
|
||||||
|
// For more info, see AMD SEV API document 55766
|
||||||
|
sevPolicyBitSevEs = 0x4
|
||||||
)
|
)
|
||||||
|
|
||||||
var kernelParams = []Param{
|
var kernelParams = []Param{
|
||||||
@ -140,6 +146,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
|||||||
},
|
},
|
||||||
vmFactory: factory,
|
vmFactory: factory,
|
||||||
snpGuest: config.SevSnpGuest,
|
snpGuest: config.SevSnpGuest,
|
||||||
|
numVCPUs: config.NumVCPUs,
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ConfidentialGuest {
|
if config.ConfidentialGuest {
|
||||||
@ -409,6 +416,34 @@ func (q *qemuAmd64) setupSEVGuestPreAttestation(ctx context.Context, config sev.
|
|||||||
return attestationId, nil
|
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
|
// wait for prelaunch attestation to complete
|
||||||
func (q *qemuAmd64) sevGuestPreAttestation(ctx context.Context,
|
func (q *qemuAmd64) sevGuestPreAttestation(ctx context.Context,
|
||||||
qmp *govmmQemu.QMP, config sev.GuestPreAttestationConfig) error {
|
qmp *govmmQemu.QMP, config sev.GuestPreAttestationConfig) error {
|
||||||
@ -447,9 +482,9 @@ func (q *qemuAmd64) sevGuestPreAttestation(ctx context.Context,
|
|||||||
|
|
||||||
secrets := []*pb.RequestDetails{&requestDetails}
|
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 {
|
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[:])
|
launchDigestBase64 := b64.StdEncoding.EncodeToString(launchDigest[:])
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user