Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

snp: more VLEK support and fixes #201

Merged
merged 1 commit into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ based on a set of trusted CAs and signed metadata describing the software stack.
## Prerequisites

- A Linux platform
- For TPM attestation, access to `/dev/tpm0`.
- For AMD SEV-SNP an SNP-capable AMD server
- For TPM attestation, access to `/dev/tpmrm0` or `/dev/tpm0`.
- For AMD SEV-SNP an SNP-capable AMD server and an SNP VM with access to `/dev/sev-guest`
- Building the *cmcd* requires *go* (https://golang.org/doc/install)
- Building AWS Firmware (OVMF) for running the CMC within AWS AMD SEV-SNP virtual machines
requires [Nix](https://nixos.org/download/)

## Quick Start

Expand Down
19 changes: 8 additions & 11 deletions attestationreport/validationreport.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ type TpmResult struct {
}

type SnpResult struct {
VersionMatch Result `json:"reportVersionMatch"`
FwCheck VersionCheck `json:"fwCheck"`
TcbCheck TcbCheck `json:"tcbCheck"`
PolicyCheck PolicyCheck `json:"policyCheck"`
VersionMatch Result `json:"reportVersionMatch"`
FwCheck VersionCheck `json:"fwCheck"`
TcbCheck TcbCheck `json:"tcbCheck"`
PolicyCheck PolicyCheck `json:"policyCheck"`
ExtensionsCheck []Result `json:"extensionsCheck"`
}

type SgxResult struct {
Expand Down Expand Up @@ -210,10 +211,9 @@ type TdAttributesCheck struct {
// SignatureResults represents the results for validation of
// a provided signature and the used certificates.
type SignatureResult struct {
SignCheck Result `json:"signatureVerification"` // Result from checking the signature has been calculated with this certificate
CertChainCheck Result `json:"certChainValidation"` // Result from validatint the certification chain back to a shared root of trust
ExtensionsCheck []Result `json:"extensionsCheck,omitempty"`
ValidatedCerts [][]X509CertExtracted `json:"validatedCerts"` //Stripped information from validated x509 cert chain(s) for additional checks from the policies module
SignCheck Result `json:"signatureVerification"` // Result from checking the signature has been calculated with this certificate
CertChainCheck Result `json:"certChainValidation"` // Result from validatint the certification chain back to a shared root of trust
ValidatedCerts [][]X509CertExtracted `json:"validatedCerts"` //Stripped information from validated x509 cert chain(s) for additional checks from the policies module
}

// X509CertExtracted represents a x509 certificate with attributes
Expand Down Expand Up @@ -677,9 +677,6 @@ func (r *Result) PrintErr(format string, args ...interface{}) {
func (r *SignatureResult) PrintErr(format string, args ...interface{}) {
r.SignCheck.PrintErr("%v signature check", fmt.Sprintf(format, args...))
r.CertChainCheck.PrintErr("%v cert chain check", fmt.Sprintf(format, args...))
for _, e := range r.ExtensionsCheck {
e.PrintErr("%v extension check", fmt.Sprintf(format, args...))
}
}

func (r *VerificationResult) PrintErr() {
Expand Down
10 changes: 9 additions & 1 deletion example-setup/setup-cmc-snp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ mkdir -p "${data}"
sudo apt install -y moreutils golang-cfssl build-essential zlib1g-dev libssl-dev jq

# Install virtee sev-snp measure tools
git clone https://github.com/virtee/sev-snp-measure "${data}/"
echo "Clone virtee/sev-snp-measure tools"
git clone https://github.com/virtee/sev-snp-measure.git "${data}/sev-snp-measure"

# Clone OVMF with AWS patches
echo "Cloning AWS OVMF.."
git clone https://github.com/aws/uefi.git "${data}/uefi"
cd "${data}/uefi"
echo "Building AWS OVMF.."
nix-build --pure

# Build CMC
cd "${cmc}"
Expand Down
15 changes: 10 additions & 5 deletions example-setup/update-platform-snp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ source "${dir}/utils.sh"
export PATH=${PATH}:${HOME}/go/bin

if [[ "$#" -ne 2 ]]; then
echo "Usage: ./update-platform <data-folder> <ovmf-image> <cbor|json>"
echo "Usage: ./update-platform <data-folder> <cbor|json>"
exit 1
fi

data=$(set -e; abs_path "${1}")
input="${data}/metadata-raw"
tmp="${data}/metadata-tmp"
out="${data}/metadata-signed"
ovmf="${2}"
ser="${3}"
ser="${2}"

ovmf="${data}/uefi/result/ovmf_img.fd"

if [[ ! -d "${data}" ]]; then
echo "Data directory ${1} does not exist. Did you run the setup-cmc script? Abort.."
Expand All @@ -44,14 +45,18 @@ printf "%s\n" "${json}" > "${input}/device.description.json"
manifestjson=$(cat "${input}/rtm.manifest.json")

# Insert high-level details
manifestjson=$(echo "${json}" | jq ".details.firmware = \"${firmware}\"")
manifestjson=$(echo "${json}" | jq ".details.bootloader = \"${bootloader}\"")
manifestjson=$(echo "${manifestjson}" | jq ".details.firmware = \"${firmware}\"")
manifestjson=$(echo "${manifestjson}" | jq ".details.bootloader = \"${bootloader}\"")

json=$(cat "${dir}/metadata-raw/snp.referencevalue.template")

# TODO parameters vor vcpus and vmm-type
ref=$("${dir}/sev-snp-measure/sev-snp-measure.py" --mode snp --vcpus=2 --vmm-type=ec2 --ovmf="${ovmf}")

# Get AMD cert chain for milan
wget -O "${dir}/cert_chain" https://kdsintf.amd.com/vlek/v1/Milan/cert_chain
awk '/-----BEGIN CERTIFICATE-----/{n++} n==2' "${dir}/cert_chain" > "${dir}/ark_milan.pem"

fingerprint=$(openssl x509 -in "${dir}"/ark_milan.pem -fingerprint -noout -sha256 | sed 's/://g' | cut -d "=" -f2)

# Insert reference values
Expand Down
23 changes: 5 additions & 18 deletions snpdriver/snpdriver.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ const (
DER
)

type SigningKey int

const (
VCEK = iota
VLEK
)
const (
snpChainFile = "akchain.pem"
signingChainFile = "ikchain.pem"
Expand Down Expand Up @@ -325,16 +319,9 @@ func getSnpCertChain(addr string) ([]*x509.Certificate, error) {
return nil, fmt.Errorf("failed to decode SNP report: %w", err)
}

arkey := (s.KeySelection >> 2) & 0x7
var signingKey SigningKey
if arkey == 0 {
log.Trace("VCEK is used to sign attestation report")
signingKey = VCEK
} else if arkey == 1 {
log.Trace("VLEK is used to sign attestation report")
signingKey = VLEK
} else {
return nil, fmt.Errorf("could not determine SNP attestation report signing key")
akType, err := verify.GetAkType(s.KeySelection)
if err != nil {
return nil, fmt.Errorf("could not determine SNP attestation report attestation key")
}

// TODO mandate server authentication in the future, otherwise
Expand All @@ -344,15 +331,15 @@ func getSnpCertChain(addr string) ([]*x509.Certificate, error) {

var signingCert *x509.Certificate
var caUrl string
if signingKey == VCEK {
if akType == verify.VCEK {
// VCEK is used, simply request EST enrollment for SNP chip ID and TCB
log.Trace("Enrolling VCEK via EST")
signingCert, err = client.SnpEnroll(addr, s.ChipId, s.CurrentTcb)
if err != nil {
return nil, fmt.Errorf("failed to enroll SNP: %w", err)
}
caUrl = milanUrlVcek
} else if signingKey == VLEK {
} else if akType == verify.VLEK {
// VLEK is used, in this case we fetch the VLEK from the host
vlek, err := getVlek()
if err != nil {
Expand Down
Loading
Loading