From e09a2149be3dae8803b7815df58cb2b87fd7a4b6 Mon Sep 17 00:00:00 2001 From: Ruoyu Ying Date: Mon, 5 Aug 2024 16:19:17 +0800 Subject: [PATCH] constellation: update document and add patch Signed-off-by: Ruoyu Ying --- README.md | 10 +- deployment/Constellation/constellation.md | 31 +- .../constellation_qemu_tdx.patch | 608 ++++++++++++++++++ docs/constellation_config_setting.png | Bin 0 -> 55436 bytes 4 files changed, 643 insertions(+), 6 deletions(-) create mode 100644 deployment/Constellation/constellation_qemu_tdx.patch create mode 100644 docs/constellation_config_setting.png diff --git a/README.md b/README.md index 9551d32..2b56210 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ In above diagram: -- **CCNP** is used to calculate the measurement for node, namespace, +- **CIMA (Container Integrity Measurement Agent)** is used to calculate the measurement for node, namespace, POD and cluster level. -- **CC Trusted API** provides unified API to tenant to access measurement, event log +- **Evidence API** provides unified API to tenant to access measurement, event log and quote (report). ## 2. Confidential Cluster @@ -32,7 +32,7 @@ and quote (report). | Full Disk Encryption | [Yes](https://cloud.google.com/compute/docs/disks/customer-managed-encryption) | [Yes](https://learn.microsoft.com/en-us/azure/virtual-machines/disk-encryption-overview) | | Key | customer-managed encryption keys (CMEK) | PMK (platform-managed key) and CMK (customer-managed key) | | Attestation | [Google Managed vTPM](https://cloud.google.com/confidential-computing/confidential-vm/docs/attestation) | [Microsoft Azure Attestation](https://azure.microsoft.com/en-us/products/azure-attestation/)/[IntelĀ® Trust Authority](https://www.intel.com/content/www/us/en/security/trust-authority.html) | -| Tutorial | [Here](https://cloud.google.com/kubernetes-engine/docs/how-to/confidential-gke-nodes#enabling_in_a_new_cluster) | [here](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview) +| Tutorial | [Here](https://cloud.google.com/kubernetes-engine/docs/how-to/confidential-gke-nodes#enabling_in_a_new_cluster) | [Here](https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-vm-overview) ## 3. Deployment @@ -41,7 +41,7 @@ There are 3 options creating a confidential cluster. - Create a few confidential VMs (CVMs) and deploy Kubernetes within them. The CVMs can be on local hosts if you have supported hardware. The CVMs can also be applied from CSP. The document [csp_cvm.md](./deployment/csp_cvm.md) shows how to apply for a TD on Google Cloud or Azure and start a Kubernetes cluster in the single confidential node. - Create [Confidential GKE node](https://cloud.google.com/blog/products/identity-security/announcing-general-availability-of-confidential-gke-nodes) on Google cloud. -- Create a Constellation based confidential cluster on top of a TDX machine. Follow the steps [here](./deployment/constellation.md) to deploy the cluster. +- Create a Constellation based confidential cluster on top of a TDX machine. Follow the steps [here](./deployment/Constellation/constellation.md) to deploy the cluster. -Find details in [deployment guide](./deployment/Constellation/constellation.md). +Find details in [deployment guide](./deployment/). diff --git a/deployment/Constellation/constellation.md b/deployment/Constellation/constellation.md index ed4ddd7..700d1c2 100644 --- a/deployment/Constellation/constellation.md +++ b/deployment/Constellation/constellation.md @@ -28,15 +28,42 @@ To leverage bare metal TDX machine to build up Constellation cluster, user need ### Step 1: Clone Constellation repo and apply patches. +Apply the patch to enable qemu-tdx within TDX bare-metal host using qemu. + +The patch focusing on enabling the qemu-tdx option within Constellation. + +The support for TDX attestation is done through the [go-tdx-qpl](https://github.com/Ruoyu-y/go-tdx-qpl) library which is a fork of Edgeless Sys's [go-tdx-qpl](https://github.com/edgelesssys/go-tdx-qpl) library. Most of the changes focusing the support of TDX 1.5 attestation and verifications. Since Constellation needs to specify the version and hash of dependencies within the code, these changes are directly applied within the patch. + ```bash # clone the constellation repo and apply patches. git clone https://github.com/edgelesssys/constellation.git git checkout fe65a6da76d03f0bed841ae36f33ff22d2567700 git checkout -b constellation-qemu-tdx -git apply constellation_qemu_tdx.patch +git apply ./constellation_qemu_tdx.patch ``` ### (Optional) Step 2: Setup proxy if required +If user are building and running the confidential cluster under proxy, some files need to be modified to bypass the proxy issues. + +Here listed the files that need to be modified: +``` +# Add proxy setting to the files as environment variables +# e.g. add lines 'export http_proxy=' to export http_proxy, https_proxy and no_proxy in the script +image/base/mkosi.skeleton/etc/profile.d/constellation.sh + +# Add extra 'env' section in the configuration +# e.g. env = {"HTTP_PROXY": , "HTTPS_PROXY": , "NO_PROXY": } +image/system/BUILD.bazel + +# Add proxy as environment variables under the service section +# e.g. Environment="HTTP_PROXY=". Add http_proxy, https_proxy and no_proxy +image/base/mkosi.skeleton/usr/lib/systemd/system/containerd.service.d/local.conf +image/base/mkosi.skeleton/usr/lib/systemd/system/kubelet.service + +# Add proxy during execution +# e.g. ExecStart=/bin/bash -c "echo http_proxy= >> /run/constellation.env". Echo http_proxy, https_proxy and no_proxy in the file. +image/sysroot-tree/usr/lib/systemd/system/configure-constel-csp.service +``` ### Step 3: Build Constellation image for QEMU-TDX option Build a Constellation image that works for QEMU-TDX option. @@ -81,6 +108,8 @@ User need to modify the configuration before starting up the cluster. Modificati 3. check the value of `metadataAPIServer` and make sure it equals to the value you just pushed in the CLI generation step. 4. change the measurements of TDX like what shows in the picture +measurement setting in constellation-conf.yaml + User could then use the simple command to start up the Constellation confidential cluster. ```bash # add '--debug' flag to check the debug information diff --git a/deployment/Constellation/constellation_qemu_tdx.patch b/deployment/Constellation/constellation_qemu_tdx.patch new file mode 100644 index 0000000..99b198f --- /dev/null +++ b/deployment/Constellation/constellation_qemu_tdx.patch @@ -0,0 +1,608 @@ +From b4692b8970ebc86747bc041caa130e9337a00560 Mon Sep 17 00:00:00 2001 +From: Ruoyu Ying +Date: Mon, 5 Aug 2024 15:17:59 +0800 +Subject: [PATCH] qemu-tdx: support option 'qemu-tdx' in constellation + +* support constellation deployment on bare-metal TDX machine using + option 'qemu-tdx' + +Signed-off-by: Ruoyu Ying +--- + bazel/toolchains/go_module_deps.bzl | 34 +++++++++++++++-- + cli/internal/cloudcmd/tfvars.go | 6 +++ + go.mod | 6 ++- + go.sum | 12 +++++- + .../usr/lib/systemd/system/kubelet.service | 1 + + image/system/variants.bzl | 9 +++++ + internal/attestation/attestation.go | 8 ++-- + internal/attestation/initialize/BUILD.bazel | 2 +- + internal/attestation/initialize/initialize.go | 12 ++++-- + internal/attestation/tdx/BUILD.bazel | 6 +-- + internal/attestation/tdx/issuer.go | 4 +- + internal/attestation/tdx/tdx.go | 25 ++++++++++--- + internal/attestation/tdx/validator.go | 4 +- + internal/attestation/variant/variant.go | 2 +- + internal/config/config.go | 6 +++ + internal/config/validation.go | 8 +++- + .../qemu/modules/instance_group/main.tf | 8 ++-- + .../modules/instance_group/tdx_domain.xsl | 37 ++++++++++++++----- + terraform/infrastructure/qemu/outputs.tf | 16 ++++---- + 19 files changed, 156 insertions(+), 50 deletions(-) + +diff --git a/bazel/toolchains/go_module_deps.bzl b/bazel/toolchains/go_module_deps.bzl +index a95194d23..6d47334ff 100644 +--- a/bazel/toolchains/go_module_deps.bzl ++++ b/bazel/toolchains/go_module_deps.bzl +@@ -1409,12 +1409,12 @@ def go_dependencies(): + version = "v0.0.0-20240513062303-05f8770a633d", + ) + go_repository( +- name = "com_github_edgelesssys_go_tdx_qpl", ++ name = "com_github_Ruoyu-y_go_tdx_qpl", + build_file_generation = "on", + build_file_proto_mode = "disable_global", +- importpath = "github.com/edgelesssys/go-tdx-qpl", +- sum = "h1:TCGUmmH50cQBGXPJsn32APf93fmWQXcSMi7pMbDPtV0=", +- version = "v0.0.0-20240123150912-dcad3c41ec5f", ++ importpath = "github.com/Ruoyu-y/go-tdx-qpl", ++ sum = "h1:V20ZcC5Hz/84OJovLSm0J+uAfS2TuEvJG/UIgYRk76k=", ++ version = "v0.0.0-20240730013531-9e0d36f055d8", + ) + go_repository( + name = "com_github_eggsampler_acme_v3", +@@ -7236,3 +7236,29 @@ def go_dependencies(): + sum = "h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=", + version = "v2.4.0", + ) ++ go_repository( ++ name = "cc_api_cc_trusted_vmsdk", ++ build_file_generation = "on", ++ build_file_proto_mode = "disable_global", ++ importpath = "github.com/cc-api/cc-trusted-vmsdk/src/golang/cctrusted_vm", ++ sum = "h1:CYPI9/gwWzxn8ywlEPzEZqwYv8yZArGpJAkgsnHXRr8=", ++ version = "v0.0.0-20240730011201-862206e5bd59", ++ ) ++ go_repository( ++ name = "com_github_cc_api_evidence_api_common_golang_evidence_api", ++ build_file_generation = "on", ++ build_file_proto_mode = "disable_global", ++ importpath = "github.com/cc-api/evidence-api/common/golang/evidence_api", ++ sum = "h1:IjmvJTssPaDuC/qkSDaLFv6u+9MFFH+nmTr4Duj6KhM=", ++ version = "v0.0.0-20240729064808-21e12aa810c8", ++ ) ++ go_repository( ++ name = "com_github_mdlayher_vsock", ++ build_file_generation = "on", ++ build_file_proto_mode = "disable_global", ++ importpath = "github.com/mdlayher/vsock", ++ sum = "h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=", ++ version = "v1.2.1", ++ ) ++ ++ +diff --git a/cli/internal/cloudcmd/tfvars.go b/cli/internal/cloudcmd/tfvars.go +index 50df8dbcc..97da80fc8 100644 +--- a/cli/internal/cloudcmd/tfvars.go ++++ b/cli/internal/cloudcmd/tfvars.go +@@ -333,6 +333,12 @@ func qemuTerraformVars( + } + } + ++ // prepare boot mode according to attestation variant ++ bootMode := "uefi" ++ if conf.Attestation.QEMUTDX != nil { ++ bootMode = "direct-linux-boot" ++ } ++ + metadataLibvirtURI := libvirtURI + if libvirtSocketPath != "." { + metadataLibvirtURI = "qemu:///system" +diff --git a/go.mod b/go.mod +index feba121f5..a0cd5e1fa 100644 +--- a/go.mod ++++ b/go.mod +@@ -54,6 +54,7 @@ require ( + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0 + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 + github.com/BurntSushi/toml v1.3.2 ++ github.com/Ruoyu-y/go-tdx-qpl v0.0.0-20240722062019-ac6f93ac6558 + github.com/aws/aws-sdk-go v1.53.0 + github.com/aws/aws-sdk-go-v2 v1.26.1 + github.com/aws/aws-sdk-go-v2/config v1.27.13 +@@ -73,7 +74,6 @@ require ( + github.com/coreos/go-systemd/v22 v22.5.0 + github.com/docker/docker v26.1.2+incompatible + github.com/edgelesssys/go-azguestattestation v0.0.0-20240513062303-05f8770a633d +- github.com/edgelesssys/go-tdx-qpl v0.0.0-20240123150912-dcad3c41ec5f + github.com/foxboron/go-uefi v0.0.0-20240128152106-48be911532c2 + github.com/fsnotify/fsnotify v1.7.0 + github.com/go-playground/locales v0.14.1 +@@ -202,6 +202,8 @@ require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect + github.com/blang/semver/v4 v4.0.0 // indirect ++ github.com/cc-api/cc-trusted-vmsdk/src/golang/cctrusted_vm v0.0.0-20240730011201-862206e5bd59 // indirect ++ github.com/cc-api/evidence-api/common/golang/evidence_api v0.0.0-20240729064808-21e12aa810c8 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/cloudflare/circl v1.3.7 // indirect +@@ -303,6 +305,8 @@ require ( + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect ++ github.com/mdlayher/socket v0.5.1 // indirect ++ github.com/mdlayher/vsock v1.2.1 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect +diff --git a/go.sum b/go.sum +index b4fc2ac44..8fff3a9b4 100644 +--- a/go.sum ++++ b/go.sum +@@ -101,6 +101,8 @@ github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7 + github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= + github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= + github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= ++github.com/Ruoyu-y/go-tdx-qpl v0.0.0-20240722062019-ac6f93ac6558 h1:FZSzMYWl3jAPeTpn+iJwuwBAE7kBQKY31NxmwXl0MxE= ++github.com/Ruoyu-y/go-tdx-qpl v0.0.0-20240722062019-ac6f93ac6558/go.mod h1:InH5Rs9J5LYlL9TXTduuVxm87ya02jkTn9JwUTPehz4= + github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= + github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= + github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= +@@ -191,6 +193,10 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj + github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= + github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= + github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= ++github.com/cc-api/cc-trusted-vmsdk/src/golang/cctrusted_vm v0.0.0-20240730011201-862206e5bd59 h1:CYPI9/gwWzxn8ywlEPzEZqwYv8yZArGpJAkgsnHXRr8= ++github.com/cc-api/cc-trusted-vmsdk/src/golang/cctrusted_vm v0.0.0-20240730011201-862206e5bd59/go.mod h1:3g+ZHQ8Gb78lRXUaaEB5MwioiJGxlPnQCqwY7sq3+to= ++github.com/cc-api/evidence-api/common/golang/evidence_api v0.0.0-20240729064808-21e12aa810c8 h1:IjmvJTssPaDuC/qkSDaLFv6u+9MFFH+nmTr4Duj6KhM= ++github.com/cc-api/evidence-api/common/golang/evidence_api v0.0.0-20240729064808-21e12aa810c8/go.mod h1:R1LPex62L4Ftnnw5vWp5sFNI5j8tnHtf0oQKvLvm9Pw= + github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= + github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= + github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +@@ -260,8 +266,6 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU + github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= + github.com/edgelesssys/go-azguestattestation v0.0.0-20240513062303-05f8770a633d h1:XcoMVhZve0RRkSxFDn9Bs/z4FpHqZ3eHgVNWNCNOkqc= + github.com/edgelesssys/go-azguestattestation v0.0.0-20240513062303-05f8770a633d/go.mod h1:Lz4QaomI4wU2YbatD4/W7vatW2Q35tnkoJezB1clscc= +-github.com/edgelesssys/go-tdx-qpl v0.0.0-20240123150912-dcad3c41ec5f h1:TCGUmmH50cQBGXPJsn32APf93fmWQXcSMi7pMbDPtV0= +-github.com/edgelesssys/go-tdx-qpl v0.0.0-20240123150912-dcad3c41ec5f/go.mod h1:IC72qyykUIWl0ZmSk53L4xbLCFDBEGZVaujUmPQOEyw= + github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= + github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= + github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +@@ -633,6 +637,10 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A + github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= + github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= + github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= ++github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= ++github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= ++github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ= ++github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE= + github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= + github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +diff --git a/image/base/mkosi.skeleton/usr/lib/systemd/system/kubelet.service b/image/base/mkosi.skeleton/usr/lib/systemd/system/kubelet.service +index bfe1b8b85..2b6ff21c9 100644 +--- a/image/base/mkosi.skeleton/usr/lib/systemd/system/kubelet.service ++++ b/image/base/mkosi.skeleton/usr/lib/systemd/system/kubelet.service +@@ -9,6 +9,7 @@ Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/boot + Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" + # This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically + EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env ++EnvironmentFile=/run/constellation.env + # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use + # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. + EnvironmentFile=-/etc/default/kubelet +diff --git a/image/system/variants.bzl b/image/system/variants.bzl +index 3cca05c95..93fd0ec68 100644 +--- a/image/system/variants.bzl ++++ b/image/system/variants.bzl +@@ -33,6 +33,10 @@ VARIANTS = [ + "attestation_variant": "qemu-vtpm", + "csp": "qemu", + }, ++ { ++ "attestation_variant": "qemu-tdx", ++ "csp": "qemu", ++ }, + ] + + STREAMS = [ +@@ -132,6 +136,11 @@ attestation_variant_settings = { + "constel.attestation-variant": "qemu-vtpm", + }, + }, ++ "qemu-tdx": { ++ "kernel_command_line_dict": { ++ "constel.attestation-variant": "qemu-tdx", ++ }, ++ }, + } + + stream_settings = { +diff --git a/internal/attestation/attestation.go b/internal/attestation/attestation.go +index d5e458012..49230bc52 100644 +--- a/internal/attestation/attestation.go ++++ b/internal/attestation/attestation.go +@@ -30,7 +30,7 @@ package attestation + + import ( + "bytes" +- "crypto/sha256" ++ "crypto/sha512" + + "github.com/edgelesssys/constellation/v2/internal/crypto" + ) +@@ -65,9 +65,9 @@ func DeriveClusterID(secret, salt []byte) ([]byte, error) { + + // MakeExtraData binds userData to a random nonce used in attestation. + func MakeExtraData(userData []byte, nonce []byte) []byte { +- data := append([]byte{}, userData...) +- data = append(data, nonce...) +- digest := sha256.Sum256(data) ++ data := append([]byte{}, nonce...) ++ data = append(data, userData...) ++ digest := sha512.Sum512(data) + return digest[:] + } + +diff --git a/internal/attestation/initialize/BUILD.bazel b/internal/attestation/initialize/BUILD.bazel +index 18bbcf260..3c18c0675 100644 +--- a/internal/attestation/initialize/BUILD.bazel ++++ b/internal/attestation/initialize/BUILD.bazel +@@ -9,7 +9,7 @@ go_library( + deps = [ + "//internal/attestation/measurements", + "//internal/attestation/tdx", +- "@com_github_edgelesssys_go_tdx_qpl//tdx", ++ "@com_github_Ruoyu-y_go_tdx_qpl//tdx", + "@com_github_google_go_tpm//legacy/tpm2", + ], + ) +diff --git a/internal/attestation/initialize/initialize.go b/internal/attestation/initialize/initialize.go +index 65bfe349c..008093e8e 100644 +--- a/internal/attestation/initialize/initialize.go ++++ b/internal/attestation/initialize/initialize.go +@@ -13,9 +13,9 @@ import ( + "errors" + "io" + ++ tdxapi "github.com/Ruoyu-y/go-tdx-qpl/tdx" + "github.com/edgelesssys/constellation/v2/internal/attestation/measurements" + "github.com/edgelesssys/constellation/v2/internal/attestation/tdx" +- tdxapi "github.com/edgelesssys/go-tdx-qpl/tdx" + "github.com/google/go-tpm/legacy/tpm2" + ) + +@@ -57,7 +57,11 @@ func IsNodeBootstrapped(openDevice func() (io.ReadWriteCloser, error)) (bool, er + } + + func tdxIsNodeBootstrapped(handle tdx.Device) (bool, error) { +- tdMeasure, err := tdxapi.ReadMeasurements(handle) ++ tdxVersion := tdx.GetDeviceVersion() ++ if tdxVersion == "" { ++ return false, errors.New("Device Version not found") ++ } ++ tdMeasure, err := tdxapi.ReadMeasurements(handle, tdxVersion) + if err != nil { + return false, err + } +@@ -117,7 +121,9 @@ func tpmIsNodeBootstrapped(tpm io.ReadWriteCloser) (bool, error) { + } + + func tdxMarkNodeAsBootstrapped(handle tdx.Device, clusterID []byte) error { +- return tdxapi.ExtendRTMR(handle, clusterID, measurements.RTMRIndexClusterID) ++ //comment for now as extend RTMR is currently not supported in upstream kernel ++ //return tdxapi.ExtendRTMR(handle, clusterID, measurements.RTMRIndexClusterID) ++ return nil + } + + func tpmMarkNodeAsBootstrapped(tpm io.ReadWriteCloser, clusterID []byte) error { +diff --git a/internal/attestation/tdx/BUILD.bazel b/internal/attestation/tdx/BUILD.bazel +index ddcdf68c7..3352458ba 100644 +--- a/internal/attestation/tdx/BUILD.bazel ++++ b/internal/attestation/tdx/BUILD.bazel +@@ -14,8 +14,8 @@ go_library( + "//internal/attestation/measurements", + "//internal/attestation/variant", + "//internal/config", +- "@com_github_edgelesssys_go_tdx_qpl//tdx", +- "@com_github_edgelesssys_go_tdx_qpl//verification", +- "@com_github_edgelesssys_go_tdx_qpl//verification/types", ++ "@com_github_Ruoyu-y_go_tdx_qpl//tdx", ++ "@com_github_Ruoyu-y_go_tdx_qpl//verification", ++ "@com_github_Ruoyu-y_go_tdx_qpl//verification/types", + ], + ) +diff --git a/internal/attestation/tdx/issuer.go b/internal/attestation/tdx/issuer.go +index 0dadb4b3c..08044012c 100644 +--- a/internal/attestation/tdx/issuer.go ++++ b/internal/attestation/tdx/issuer.go +@@ -11,9 +11,9 @@ import ( + "encoding/json" + "fmt" + ++ "github.com/Ruoyu-y/go-tdx-qpl/tdx" + "github.com/edgelesssys/constellation/v2/internal/attestation" + "github.com/edgelesssys/constellation/v2/internal/attestation/variant" +- "github.com/edgelesssys/go-tdx-qpl/tdx" + ) + + // Issuer is the TDX attestation issuer. +@@ -50,7 +50,7 @@ func (i *Issuer) Issue(_ context.Context, userData []byte, nonce []byte) (attDoc + } + defer handle.Close() + +- quote, err := tdx.GenerateQuote(handle, attestation.MakeExtraData(userData, nonce)) ++ quote, err := tdx.GenerateQuote(handle, userData, nonce) + if err != nil { + return nil, fmt.Errorf("generating quote: %w", err) + } +diff --git a/internal/attestation/tdx/tdx.go b/internal/attestation/tdx/tdx.go +index ea0cb67c4..772487918 100644 +--- a/internal/attestation/tdx/tdx.go ++++ b/internal/attestation/tdx/tdx.go +@@ -12,10 +12,12 @@ import ( + "io" + "os" + ++ "github.com/Ruoyu-y/go-tdx-qpl/tdx" + "github.com/edgelesssys/constellation/v2/internal/attestation/measurements" +- "github.com/edgelesssys/go-tdx-qpl/tdx" + ) + ++var deviceVersion string ++ + type tdxAttestationDocument struct { + // RawQuote is the raw TDX quote. + RawQuote []byte +@@ -46,7 +48,7 @@ func GetSelectedMeasurements(open OpenFunc, selection []int) (measurements.M, er + } + defer handle.Close() + +- tdxMeasurements, err := tdx.ReadMeasurements(handle) ++ tdxMeasurements, err := tdx.ReadMeasurements(handle, deviceVersion) + if err != nil { + return nil, err + } +@@ -73,14 +75,27 @@ func Available() bool { + + // Open opens the TDX guest device. + func Open() (Device, error) { +- handle, err := os.Open(tdx.GuestDevice) ++ deviceVersion = tdx.TdxVersion10 ++ handle, err := os.Open(tdx.GuestDevice_1_0) + if err != nil { +- return nil, err ++ handle, err = os.Open(tdx.GuestDevice_1_5) ++ if err != nil { ++ deviceVersion = "" ++ return nil, err ++ } ++ deviceVersion = tdx.TdxVersion15 + } + + return handle, nil + } + ++func GetDeviceVersion() string { ++ if deviceVersion != "" { ++ return deviceVersion ++ } ++ return "" ++} ++ + // IsTDXDevice checks if the given device is a TDX guest device. + func IsTDXDevice(device io.ReadWriteCloser) (Device, bool) { + handle, ok := device.(Device) +@@ -91,5 +106,5 @@ func IsTDXDevice(device io.ReadWriteCloser) (Device, bool) { + if !ok { + return nil, false + } +- return handle, f.Name() == tdx.GuestDevice ++ return handle, f.Name() == tdx.GuestDevice_1_0 || f.Name() == tdx.GuestDevice_1_5 + } +diff --git a/internal/attestation/tdx/validator.go b/internal/attestation/tdx/validator.go +index dcf92d742..0633d9f47 100644 +--- a/internal/attestation/tdx/validator.go ++++ b/internal/attestation/tdx/validator.go +@@ -12,12 +12,12 @@ import ( + "errors" + "fmt" + ++ "github.com/Ruoyu-y/go-tdx-qpl/verification" ++ "github.com/Ruoyu-y/go-tdx-qpl/verification/types" + "github.com/edgelesssys/constellation/v2/internal/attestation" + "github.com/edgelesssys/constellation/v2/internal/attestation/measurements" + "github.com/edgelesssys/constellation/v2/internal/attestation/variant" + "github.com/edgelesssys/constellation/v2/internal/config" +- "github.com/edgelesssys/go-tdx-qpl/verification" +- "github.com/edgelesssys/go-tdx-qpl/verification/types" + ) + + type tdxVerifier interface { +diff --git a/internal/attestation/variant/variant.go b/internal/attestation/variant/variant.go +index e71a51480..4dad1b2cf 100644 +--- a/internal/attestation/variant/variant.go ++++ b/internal/attestation/variant/variant.go +@@ -56,7 +56,7 @@ var providerAttestationMapping = map[cloudprovider.Provider][]Variant{ + cloudprovider.AWS: {AWSSEVSNP{}, AWSNitroTPM{}}, + cloudprovider.Azure: {AzureSEVSNP{}, AzureTDX{}, AzureTrustedLaunch{}}, + cloudprovider.GCP: {GCPSEVES{}, GCPSEVSNP{}}, +- cloudprovider.QEMU: {QEMUVTPM{}}, ++ cloudprovider.QEMU: {QEMUVTPM{}, QEMUTDX{}}, + cloudprovider.OpenStack: {QEMUVTPM{}}, + } + +diff --git a/internal/config/config.go b/internal/config/config.go +index e4b1fa765..a8e209d0c 100644 +--- a/internal/config/config.go ++++ b/internal/config/config.go +@@ -399,6 +399,7 @@ func Default() *Config { + GCPSEVES: &GCPSEVES{Measurements: measurements.DefaultsFor(cloudprovider.GCP, variant.GCPSEVES{})}, + GCPSEVSNP: DefaultForGCPSEVSNP(), + QEMUVTPM: &QEMUVTPM{Measurements: measurements.DefaultsFor(cloudprovider.QEMU, variant.QEMUVTPM{})}, ++ QEMUTDX: &QEMUTDX{Measurements: measurements.DefaultsFor(cloudprovider.QEMU, variant.QEMUTDX{})}, + }, + } + } +@@ -591,6 +592,8 @@ func (c *Config) SetAttestation(attestation variant.Variant) { + c.Attestation = AttestationConfig{GCPSEVSNP: currentAttestationConfigs.GCPSEVSNP} + case variant.QEMUVTPM: + c.Attestation = AttestationConfig{QEMUVTPM: currentAttestationConfigs.QEMUVTPM} ++ case variant.QEMUTDX: ++ c.Attestation = AttestationConfig{QEMUTDX: currentAttestationConfigs.QEMUTDX} + } + } + +@@ -662,6 +665,9 @@ func (c *Config) GetAttestationConfig() AttestationCfg { + if c.Attestation.QEMUVTPM != nil { + return c.Attestation.QEMUVTPM + } ++ if c.Attestation.QEMUTDX != nil { ++ return c.Attestation.QEMUTDX ++ } + return &DummyCfg{} + } + +diff --git a/internal/config/validation.go b/internal/config/validation.go +index fab69ff29..238baec29 100644 +--- a/internal/config/validation.go ++++ b/internal/config/validation.go +@@ -208,6 +208,9 @@ func validateAttestation(sl validator.StructLevel) { + if attestation.QEMUVTPM != nil { + attestationCount++ + } ++ if attestation.QEMUTDX != nil { ++ attestationCount++ ++ } + + if attestationCount < 1 { + sl.ReportError(attestation, "Attestation", "Attestation", "no_attestation", "") +@@ -250,7 +253,7 @@ func translateNoAttestationError(ut ut.Translator, fe validator.FieldError) stri + } + + func registerNoAttestationError(ut ut.Translator) error { +- return ut.Add("no_attestation", "{0}: No attestation has been defined (requires either awsSEVSNP, awsNitroTPM, azureSEVSNP, azureTDX, azureTrustedLaunch, gcpSEVES, or qemuVTPM)", true) ++ return ut.Add("no_attestation", "{0}: No attestation has been defined (requires either awsSEVSNP, awsNitroTPM, azureSEVSNP, azureTDX, azureTrustedLaunch, gcpSEVES, qemuVTPM or qemuTDX)", true) + } + + func translateNoDefaultControlPlaneGroupError(ut ut.Translator, fe validator.FieldError) string { +@@ -373,6 +376,9 @@ func (c *Config) translateMoreThanOneAttestationError(ut ut.Translator, fe valid + if c.Attestation.QEMUVTPM != nil { + definedAttestations = append(definedAttestations, "QEMUVTPM") + } ++ if c.Attestation.QEMUTDX != nil { ++ definedAttestations = append(definedAttestations, "QEMUTDX") ++ } + + t, _ := ut.T("more_than_one_attestation", fe.Field(), strings.Join(definedAttestations, ", ")) + +diff --git a/terraform/infrastructure/qemu/modules/instance_group/main.tf b/terraform/infrastructure/qemu/modules/instance_group/main.tf +index 75ecbf2b8..eb55f739e 100644 +--- a/terraform/infrastructure/qemu/modules/instance_group/main.tf ++++ b/terraform/infrastructure/qemu/modules/instance_group/main.tf +@@ -36,10 +36,10 @@ resource "libvirt_domain" "instance_group" { + kernel = local.kernel + initrd = local.initrd + cmdline = local.cmdline +- tpm { +- backend_type = "emulator" +- backend_version = "2.0" +- } ++ //tpm { ++ // backend_type = "emulator" ++ // backend_version = "2.0" ++ //} + disk { + volume_id = element(libvirt_volume.boot_volume.*.id, count.index) + } +diff --git a/terraform/infrastructure/qemu/modules/instance_group/tdx_domain.xsl b/terraform/infrastructure/qemu/modules/instance_group/tdx_domain.xsl +index 69257a7b7..77ebc9dd8 100644 +--- a/terraform/infrastructure/qemu/modules/instance_group/tdx_domain.xsl ++++ b/terraform/infrastructure/qemu/modules/instance_group/tdx_domain.xsl +@@ -41,13 +41,6 @@ + + + +- +- +- +- +- 0x10000001 +- vsock:2:4050 +- + + + +@@ -59,6 +52,26 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -84,9 +97,15 @@ + + + +- ++ + + ++ ++ ++ ++ ++ ++ + + +- ++ +\ No newline at end of file +diff --git a/terraform/infrastructure/qemu/outputs.tf b/terraform/infrastructure/qemu/outputs.tf +index 9ac51031c..2d6511ce5 100644 +--- a/terraform/infrastructure/qemu/outputs.tf ++++ b/terraform/infrastructure/qemu/outputs.tf +@@ -56,11 +56,11 @@ output "validate_constellation_initrd" { + description = "Validation placeholder. Do not consume as output." + } + +-output "validate_constellation_cmdline" { +- value = null +- precondition { +- condition = var.constellation_boot_mode != "direct-linux-boot" || length(var.constellation_cmdline) > 0 +- error_message = "constellation_cmdline must be set if constellation_boot_mode is 'direct-linux-boot'" +- } +- description = "Validation placeholder. Do not consume as output." +-} ++#output "validate_constellation_cmdline" { ++# value = null ++# precondition { ++# condition = var.constellation_boot_mode != "direct-linux-boot" || length(var.constellation_cmdline) > 0 ++# error_message = "constellation_cmdline must be set if constellation_boot_mode is 'direct-linux-boot'" ++# } ++# description = "Validation placeholder. Do not consume as output." ++#} +-- +2.44.0.windows.1 + diff --git a/docs/constellation_config_setting.png b/docs/constellation_config_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..b3c706cdf0cce8438285759a026d0bc5e37a0b7e GIT binary patch literal 55436 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ˮ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⪙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 CF!kO5 literal 0 HcmV?d00001