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

Improvements #200

Merged
merged 12 commits into from
Sep 9, 2024
Merged
13 changes: 13 additions & 0 deletions attestationreport/attestationreport.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ type ReferenceValue struct {
Sgx *SGXDetails `json:"sgx,omitempty" cbor:"8,keyasint,omitempty"`
Description string `json:"description,omitempty" cbor:"9,keyasint,omitempty"`
EventData *EventData `json:"eventdata,omitempty" cbor:"10,keyasint,omitempty"`

manifest Manifest
}

// AppDescription represents the attestation report
Expand Down Expand Up @@ -276,6 +278,9 @@ type Environment struct {
Value string `json:"value" cbor:"1,keyasint"`
}

// Generic manifest
type Manifest interface{}

// AppManifest represents the attestation report
// element of type 'App Manifest'
type AppManifest struct {
Expand Down Expand Up @@ -387,3 +392,11 @@ type AttestationReport struct {
CompanyDescription []byte `json:"companyDescription,omitempty" cbor:"5,keyasint,omitempty"`
DeviceDescription []byte `json:"deviceDescription" cbor:"6,keyasint"`
}

func (r *ReferenceValue) GetManifest() Manifest {
return r.manifest
}

func (r *ReferenceValue) SetManifest(m Manifest) {
r.manifest = m
}
3 changes: 2 additions & 1 deletion attestationreport/validationreport.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ type DigestResult struct {
Description string `json:"description,omitempty"` // Optional description, measured PCR in case of PCR result
Success bool `json:"success"` // Indicates whether match was found
Type string `json:"type,omitempty"` // On fail, indicates whether digest is reference or measurement
EventData *EventData `json:"eventdata,omitempty"` // data that was included from bioseventlog
EventData *EventData `json:"eventData,omitempty"` // data that was included from bioseventlog
CtrData *CtrData `json:"ctrData,omitempty"` // data that was included from container log
}

type VersionCheck struct {
Expand Down
2 changes: 2 additions & 0 deletions est/estserver/snp.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ func (s *Server) unlockVcekMutex() {
// in DER format from the cache or downloads it from the AMD server if not present
func (s *Server) getVcek(chipId []byte, tcb uint64) (*x509.Certificate, error) {

log.Tracef("Fetching VCEK for chip ID %v, TCB %x", hex.EncodeToString(chipId), tcb)

// Allow only one download and caching of the VCEK certificate in parallel
// as the AMD KDF server allows only one request in 10s
s.lockVcekMutex()
Expand Down
28 changes: 28 additions & 0 deletions example-setup/metadata-raw/snp.referencevalue.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"type": "SNP Reference Value",
"sha384": "",
"snp": {
"version": 0,
"caFingerprint": "",
"policy": {
"type": "SNP Policy",
"SingleSocket": false,
"Debug": false,
"Migration": false,
"Smt": false,
"AbiMajor": 0,
"AbiMinor": 0
},
"fw": {
"build": 0,
"major": 0,
"minor": 0
},
"tcb": {
"bl": 0,
"tee": 0,
"snp": 0,
"ucode": 0
}
}
}
58 changes: 58 additions & 0 deletions example-setup/setup-cmc-snp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

set -euo pipefail

trap '[ $? -eq 0 ] && exit 0; printf "%s failed\n" "$0"' EXIT
dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)"
source "${dir}/utils.sh"
export PATH=${PATH}:${HOME}/go/bin

if [[ "$#" -ne 3 ]]; then
echo "Usage: ./setup-cmc <cmc-folder> <data-folder> <cbor|json>"
exit
fi

cmc=$(set -e; abs_path "$1")
data=$(set -e; abs_path "$2")
ser="${3}"
client="docker"

if [[ ! -d "${cmc}" ]]; then
echo "CMC directory does not exist. Did you clone the repository? Abort.."
exit 1
fi

if [[ -d "${data}" ]]; then
echo "Data directory does already exist. Please choose a new directory. Abort.."
exit 1
fi

echo "Using CMC: ${cmc}"
echo "Using ${data} as directory for local data"

# Create a folder for the cmc configuration and metadata
mkdir -p "${data}"

# Install dependencies
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}/"

# Build CMC
cd "${cmc}"
echo "Building CMC.."
go build ./...

# Install CMC to $GOPATH/bin
echo "Installing CMC"
go install ./...

# Copy metadata templates
cp -r "${cmc}/example-setup/"* "${data}"

# Generate a PKI
"${data}/setup-pki" -i "${data}" -o "${data}/pki"

# Generate and sign platform (RTM and OS) metadata
"${data}/update-platform-snp" "${data}" "${ser}"
22 changes: 11 additions & 11 deletions example-setup/update-container-manifest-live
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ echo "Creating reference values for container: ${target} with args ${args}"
echo "Using ${data} as directory for local data"

# Delete temporary manifests
rm -rf "${tmp}"/*
rm -rf "${tmp:?}"/*

# Temporarily configure runc to generate reference values
if [ ! -f "${runc_config}" ]; then
exists=false
sudo printf "{\"generateRefVals\":\"true\"}" > "${runc_config}"
echo "{\"generateRefVals\":\"true\"}" | tee "${runc_config}"
else
exists=true
json=$(cat "${runc_config}")
Expand All @@ -76,21 +76,21 @@ sudo rm -f /tmp/container-refs
echo "Generating reference values for ${client} client"
if [[ "${client}" == "ctr" ]]; then
containers=("${target}")
sudo ctr image pull ${target}
sudo ctr image pull "${target}"
set +e
sudo ctr run --detach ${args} ${target} REF_CONTAINER
sudo ctr run --detach ${args} "${target}" REF_CONTAINER
sudo ctr task kill -s SIGKILL REF_CONTAINER
sudo ctr container delete REF_CONTAINER
set -e
elif [[ "${client}" == "shim" ]]; then
containers=("${target}")
sudo ctr image pull ${target}
sudo ctr image pull "${target}"
set +e
sudo ctr run --runtime ${runtime} -t --rm ${args} ${target} CMC_GENERATE_APP_MANIFEST
sudo ctr run --runtime "${runtime}" -t --rm ${args} "${target}" CMC_GENERATE_APP_MANIFEST
set -e
elif [[ "${client}" == "docker" ]]; then
containers=("${target}")
sudo docker run ${args} ${target}
sudo docker run ${args} "${target}"
elif [[ "${client}" == "docker-compose" ]]; then
containers=($(yq eval '.services | keys | .[]' "${target}"))
set +e
Expand All @@ -103,7 +103,7 @@ elif [[ "${client}" == "docker-compose" ]]; then
set -e
elif [[ "${client}" == "runc" ]]; then
containers=("${target}")
cd ${target}
cd "${target}"
sudo runc create references
sudo runc delete references
cd -
Expand Down Expand Up @@ -157,8 +157,8 @@ for ((i = 0; i < num_containers; i++)); do
appdesc=$(echo "${appdesc}" | jq ".name = \"${container}-${sha256}.description\"")
appdesc=$(echo "${appdesc}" | jq ".appManifest = \"${container}-${sha256}\"")
echo "Adding environment variables"
for i in "${!keys[@]}"; do
envs="{\"key\": \"${keys[$i]}\", \"value\": \"${values[$i]}\"}"
for j in "${!keys[@]}"; do
envs="{\"key\": \"${keys[${j}]}\", \"value\": \"${values[${j}]}\"}"
echo "Adding $envs"
appdesc=$(echo "${appdesc}" | jq --argjson envs "${envs}" '.environment += [$envs]')
done
Expand Down Expand Up @@ -198,4 +198,4 @@ for ((i = 0; i < num_containers; i++)); do

cmc-signing-tool -in "${tmp}/${container_name}-${sha256}.manifest.${ser}" -out "${output}/${container_name}-${sha256}.manifest.${ser}" -keys "${key}" -x5cs "${chain}"
cmc-signing-tool -in "${tmp}/device.description.${ser}" -out "${output}/device.description.${ser}" -keys "${key}" -x5cs "${chain}"
done
done
124 changes: 124 additions & 0 deletions example-setup/update-platform-snp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/bin/bash

set -euo pipefail

trap '[ $? -eq 0 ] && exit 0; printf "%s failed\n" "$0"' EXIT
dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)"
source "${dir}/utils.sh"
export PATH=${PATH}:${HOME}/go/bin

if [[ "$#" -ne 2 ]]; then
echo "Usage: ./update-platform <data-folder> <ovmf-image> <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}"

if [[ ! -d "${data}" ]]; then
echo "Data directory ${1} does not exist. Did you run the setup-cmc script? Abort.."
exit 1
fi

echo "Using ${data} as directory for local data"

# Retrieve high level details
set +e
firmware="unknown"
bootloader=$(grub-install --version)
kernel=$(uname -r)
os=$(lsb_release -sd 2>/dev/null)
set -e

# Replace existing app description in the device description (will be added through
# update-app-manifest scripts)
json=$(cat "${input}/device.description.json")
json=$(echo "${json}" | jq 'del(.appDescriptions[])')
printf "%s\n" "${json}" > "${input}/device.description.json"

# Load RTM manifest
manifestjson=$(cat "${input}/rtm.manifest.json")

# Insert high-level details
manifestjson=$(echo "${json}" | jq ".details.firmware = \"${firmware}\"")
manifestjson=$(echo "${json}" | 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}")

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

# Insert reference values
setjson "sha384" "${ref}"
setjson "snp.version" 2
setjson "snp.caFingerprint" "${fingerprint}"
setjson "snp.policy.SingleSocket" false
setjson "snp.policy.Debug" false
setjson "snp.policy.Migration" false
setjson "snp.policy.Smt" true
setjson "snp.policy.AbiMajor" 0
setjson "snp.policy.AbiMinor" 0
setjson "snp.fw.build" 3
setjson "snp.fw.major" 1
setjson "snp.fw.minor" 49
setjson "snp.tcb.bl" 2
setjson "snp.tcb.tee" 0
setjson "snp.tcb.snp" 5
setjson "snp.tcb.ucode" 55

refval="${json}"
json="${manifestjson}"

extendarr "referenceValues" "${refval}"

# Save the RTM manifest
printf "%s\n" "${json}" > "${input}/rtm.manifest.json"

# Load OS manifest
json=$(cat "${input}/os.manifest.json")

# Insert high-level details
json=$(echo "${json}" | jq ".details.kernel = \"${kernel}\"")
json=$(echo "${json}" | jq ".details.os = \"${os}\"")

# Replace existing reference values with new reference values in the OS Manifest
json=$(echo "${json}" | jq 'del(.referenceValues[])')
printf "%s\n" "${json}" > "${input}/os.manifest.json"

# Sign the metadata*
key="${data}/pki/signing-cert-key.pem"
chain="${data}/pki/signing-cert.pem,${data}/pki/ca.pem"

rm -rf "${tmp}"
rm -rf "${out}"

mkdir -p "${tmp}"
mkdir -p "${out}"

if [[ "${ser,,}" = "json" ]]; then
echo "using json serialization"
cp "${input}/rtm.manifest.json" "${tmp}/rtm.manifest.json"
cp "${input}/os.manifest.json" "${tmp}/os.manifest.json"
cp "${input}/device.description.json" "${tmp}/device.description.json"
cp "${input}/device.config.json" "${tmp}/device.config.json"
elif [[ "${ser,,}" = "cbor" ]]; then
echo "using cbor serialiation"
cmc-converter -in "${input}/rtm.manifest.json" -out "${tmp}/rtm.manifest.cbor" -outform cbor
cmc-converter -in "${input}/os.manifest.json" -out "${tmp}/os.manifest.cbor" -outform cbor
cmc-converter -in "${input}/device.description.json" -out "${tmp}/device.description.cbor" -outform cbor
cmc-converter -in "${input}/device.config.json" -out "${tmp}/device.config.cbor" -outform cbor
else
echo "serialization format ${ser} is not supported"
exit 1
fi

cmc-signing-tool -in "${tmp}/rtm.manifest.${ser}" -out "${out}/rtm.manifest.${ser}" -keys "${key}" -x5cs "${chain}"
cmc-signing-tool -in "${tmp}/os.manifest.${ser}" -out "${out}/os.manifest.${ser}" -keys "${key}" -x5cs "${chain}"
cmc-signing-tool -in "${tmp}/device.description.${ser}" -out "${out}/device.description.${ser}" -keys "${key}" -x5cs "${chain}"
cmc-signing-tool -in "${tmp}/device.config.${ser}" -out "${out}/device.config.${ser}" -keys "${key}" -x5cs "${chain}"
17 changes: 17 additions & 0 deletions example-setup/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,20 @@ extendarr() {
# Add new value
json="$(echo "${json}" | jq ".${key} += [${param}]")"
}


# Updates the JSON key given in the first argument with the value given
# in the second argument. Numbers must be \"\" quoted, if they should
# be treated as a JSON string
setjson() {
if [[ $2 == \"*\" || $2 == \'*\' ]]; then
# Parameter is string in quotes, use quotes
json="$(echo "${json}" | jq ".$1 = $2")"
elif [[ $2 =~ ^[0-9]+$ || $2 == "true" || $2 == "false" ]]; then
# Parameter is number or boolean, do not use quotes
json="$(echo "${json}" | jq ".$1 = $2")"
else
# Parameter is string, use quotes
json="$(echo "${json}" | jq ".$1 = \"$2\"")"
fi
}
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/edgelesssys/ego v1.4.1
github.com/fxamacker/cbor/v2 v2.4.0
github.com/google/go-attestation v0.4.4-0.20230613144338-a9b6eb1eb888
github.com/google/go-sev-guest v0.11.1
github.com/google/go-tpm v0.9.0
github.com/mattn/go-sqlite3 v1.14.16
github.com/opencontainers/runtime-spec v1.2.0
Expand All @@ -26,15 +27,21 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/certificate-transparency-go v1.1.6 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-configfs-tsm v0.2.2 // indirect
github.com/google/go-tspi v0.3.0 // indirect
github.com/google/logger v1.1.1 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/transport/v2 v2.2.1 // indirect
github.com/pion/udp/v2 v2.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.3.0 // indirect
Expand Down
Loading
Loading