From 97420df00630c87700944fb3e056d7ded8265505 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 7 Mar 2024 15:43:47 +0100 Subject: [PATCH] feat: attestation test on azure and default dcap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` ❯ docker run -i --rm --privileged --device /dev/sgx_enclave --net host \ matterlabsrobot/teepot-self-attestation-test-sgx-azure:latest \ | base64 -d --ignore-garbage \ | docker run -i --rm --net host matterlabsrobot/verify-attestation-sgx-azure:latest ``` Signed-off-by: Harald Hoyer --- .github/workflows/nix.yml | 11 ++-- Cargo.lock | 1 + assets/sgx_default_qcnl.conf.json | 2 +- bin/tee-self-attestation-test/Cargo.toml | 1 + bin/tee-self-attestation-test/src/main.rs | 14 +++-- bin/verify-attestation/src/main.rs | 4 +- .../Dockerfile | 23 ++++++++ .../default.nix | 52 +++++++++++++++++ .../tee-self-attestation-test.manifest.toml | 56 ++++++++++++++++++ .../Dockerfile | 25 ++++++++ .../default.nix | 49 ++++++++++++++++ .../tee-self-attestation-test.manifest.toml | 57 +++++++++++++++++++ .../default.nix | 38 +++++++++++++ .../default.nix | 34 +++++++++++ .../container-verify-attestation/default.nix | 16 ------ 15 files changed, 355 insertions(+), 28 deletions(-) create mode 100644 packages/container-self-attestation-test-sgx-azure/Dockerfile create mode 100644 packages/container-self-attestation-test-sgx-azure/default.nix create mode 100644 packages/container-self-attestation-test-sgx-azure/tee-self-attestation-test.manifest.toml create mode 100644 packages/container-self-attestation-test-sgx-dcap/Dockerfile create mode 100644 packages/container-self-attestation-test-sgx-dcap/default.nix create mode 100644 packages/container-self-attestation-test-sgx-dcap/tee-self-attestation-test.manifest.toml create mode 100644 packages/container-verify-attestation-sgx-azure/default.nix create mode 100644 packages/container-verify-attestation-sgx-dcap/default.nix delete mode 100644 packages/container-verify-attestation/default.nix diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index b1df968..e0f8aa9 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -89,10 +89,13 @@ jobs: fail-fast: false matrix: config: - - { nixpackage: 'container-vault-sgx-azure', dockerfile: 'packages/container-vault-sgx-azure/Dockerfile', tag: 'vault:latest', repository: 'teepot-vault' } - - { nixpackage: 'container-vault-unseal-sgx-azure', dockerfile: 'packages/container-vault-unseal-sgx-azure/Dockerfile', tag: 'tvu:latest', repository: 'teepot-tvu' } - - { nixpackage: 'container-vault-admin-sgx-azure', dockerfile: 'packages/container-vault-admin-sgx-azure/Dockerfile', tag: 'tva:latest', repository: 'teepot-tva' } - - { nixpackage: 'container-verify-attestation' } + - { nixpackage: 'container-vault-sgx-azure', dockerfile: 'packages/container-vault-sgx-azure/Dockerfile', repository: 'teepot-vault' } + - { nixpackage: 'container-vault-unseal-sgx-azure', dockerfile: 'packages/container-vault-unseal-sgx-azure/Dockerfile', repository: 'teepot-tvu' } + - { nixpackage: 'container-vault-admin-sgx-azure', dockerfile: 'packages/container-vault-admin-sgx-azure/Dockerfile', repository: 'teepot-tva' } + - { nixpackage: 'container-self-attestation-test-sgx-dcap', dockerfile: 'packages/container-self-attestation-test-sgx-dcap/Dockerfile', repository: 'teepot-self-attestation-test-sgx-dcap' } + - { nixpackage: 'container-self-attestation-test-sgx-azure', dockerfile: 'packages/container-self-attestation-test-sgx-azure/Dockerfile', repository: 'teepot-self-attestation-test-sgx-azure' } + - { nixpackage: 'container-verify-attestation-sgx-dcap' } + - { nixpackage: 'container-verify-attestation-sgx-azure' } steps: - uses: actions/checkout@v4 - uses: cachix/install-nix-action@v25 diff --git a/Cargo.lock b/Cargo.lock index df760cb..7de64dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2450,6 +2450,7 @@ version = "0.1.0" dependencies = [ "actix-web", "anyhow", + "base64 0.22.0", "teepot", "tracing", "tracing-log", diff --git a/assets/sgx_default_qcnl.conf.json b/assets/sgx_default_qcnl.conf.json index 25a7b7b..a2cd69e 100644 --- a/assets/sgx_default_qcnl.conf.json +++ b/assets/sgx_default_qcnl.conf.json @@ -1,5 +1,5 @@ { - "pccs_url": "https://host.containers.internal:8081/sgx/certification/v4/", + "pccs_url": "https://127.0.0.1:8081/sgx/certification/v4/", "use_secure_cert": false, "collateral_service": "https://api.trustedservices.intel.com/sgx/certification/v4/", "retry_times": 6, diff --git a/bin/tee-self-attestation-test/Cargo.toml b/bin/tee-self-attestation-test/Cargo.toml index ef6fef9..a353e20 100644 --- a/bin/tee-self-attestation-test/Cargo.toml +++ b/bin/tee-self-attestation-test/Cargo.toml @@ -9,6 +9,7 @@ repository.workspace = true [dependencies] actix-web.workspace = true anyhow.workspace = true +base64.workspace = true teepot.workspace = true tracing-log.workspace = true tracing-subscriber.workspace = true diff --git a/bin/tee-self-attestation-test/src/main.rs b/bin/tee-self-attestation-test/src/main.rs index 0d71c82..a08353c 100644 --- a/bin/tee-self-attestation-test/src/main.rs +++ b/bin/tee-self-attestation-test/src/main.rs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright (c) 2023 Matter Labs +// Copyright (c) 2023-2024 Matter Labs //! Simple TEE self-attestation test @@ -7,8 +7,8 @@ #![deny(clippy::all)] use anyhow::{Context, Result}; +use base64::{engine::general_purpose, Engine as _}; use teepot::server::attestation::get_quote_and_collateral; -use tracing::error; use tracing_log::LogTracer; use tracing_subscriber::{fmt, prelude::*, EnvFilter, Registry}; @@ -22,9 +22,11 @@ async fn main() -> Result<()> { tracing::subscriber::set_global_default(subscriber).unwrap(); let report_data = [0u8; 64]; - if let Err(e) = get_quote_and_collateral(None, &report_data) { - error!("failed to get quote and collateral: {e:?}"); - return Err(e); - } + let report = get_quote_and_collateral(None, &report_data) + .context("failed to get quote and collateral")?; + + let base64_string = general_purpose::STANDARD.encode(report.quote.as_ref()); + print!("{}", base64_string); + Ok(()) } diff --git a/bin/verify-attestation/src/main.rs b/bin/verify-attestation/src/main.rs index 14242a0..7fa15d6 100644 --- a/bin/verify-attestation/src/main.rs +++ b/bin/verify-attestation/src/main.rs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -// Copyright (c) 2023 Matter Labs +// Copyright (c) 2023-2024 Matter Labs //! Simple TEE attestation verification test @@ -19,6 +19,8 @@ fn main() -> Result<()> { .read_to_end(&mut myquote) .context("Failed to read quote from stdin")?; + println!("Verifying quote ({} bytes)...", myquote.len()); + let collateral = tee_qv_get_collateral(&myquote).context("Failed to get collateral")?; let unix_time: i64 = std::time::SystemTime::now() diff --git a/packages/container-self-attestation-test-sgx-azure/Dockerfile b/packages/container-self-attestation-test-sgx-azure/Dockerfile new file mode 100644 index 0000000..8a7fc84 --- /dev/null +++ b/packages/container-self-attestation-test-sgx-azure/Dockerfile @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Matter Labs + +FROM teepot-self-attestation-test-sgx-azure:base + +WORKDIR /app + +COPY packages/container-vault-sgx-azure/test-enclave-key.pem /tmp/ + +RUN set -eux; \ + gramine-manifest -Darch_libdir=/lib/x86_64-linux-gnu \ + -Dentrypoint=$(readlink /bin/tee-self-attestation-test) \ + -Dexecdir=/bin \ + -Dlog_level=error \ + tee-self-attestation-test.manifest.toml tee-self-attestation-test.manifest; \ + gramine-sgx-sign --manifest tee-self-attestation-test.manifest --output tee-self-attestation-test.manifest.sgx --key /tmp/test-enclave-key.pem; \ + rm /tmp/test-enclave-key.pem + +EXPOSE 8443 + +ENTRYPOINT ["/bin/sh", "-c"] +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt +CMD [ "restart-aesmd >&2; exec gramine-sgx tee-self-attestation-test" ] diff --git a/packages/container-self-attestation-test-sgx-azure/default.nix b/packages/container-self-attestation-test-sgx-azure/default.nix new file mode 100644 index 0000000..2b70db2 --- /dev/null +++ b/packages/container-self-attestation-test-sgx-azure/default.nix @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Matter Labs +{ pkgs +, vat +, nixsgx +, curl +, teepot +, bash +, coreutils +, openssl +, vault +}: +let manifest = ./tee-self-attestation-test.manifest.toml; +in pkgs.dockerTools.buildLayeredImage { + name = "teepot-self-attestation-test-sgx-azure"; + tag = "base"; + + config.Entrypoint = [ "/bin/sh" "-c" ]; + + contents = pkgs.buildEnv { + name = "image-root"; + + paths = with pkgs.dockerTools; with nixsgx;[ + bash + coreutils + openssl.out + azure-dcap-client + curl.out + teepot.teepot.tee_self_attestation_test + gramine + restart-aesmd + sgx-dcap.quote_verify + sgx-psw + usrBinEnv + binSh + caCertificates + fakeNss + ]; + pathsToLink = [ "/bin" "/lib" "/etc" "/share" "/app" ]; + postBuild = '' + mkdir -p $out/{app,etc} + cp ${manifest} $out/app/tee-self-attestation-test.manifest.toml + mkdir -p $out/var/run + mkdir -p $out/${nixsgx.sgx-psw.out}/aesm/ + touch $out/etc/sgx_default_qcnl.conf + mkdir -p $out/opt/vault/.cache $out/opt/vault/tls + ln -s ${curl.out}/lib/libcurl.so $out/${nixsgx.sgx-psw.out}/aesm/ + ln -s ${nixsgx.azure-dcap-client.out}/lib/libdcap_quoteprov.so $out/${nixsgx.sgx-psw.out}/aesm/libdcap_quoteprov.so.1 + printf "precedence ::ffff:0:0/96 100\n" > $out/etc/gai.conf + ''; + }; +} diff --git a/packages/container-self-attestation-test-sgx-azure/tee-self-attestation-test.manifest.toml b/packages/container-self-attestation-test-sgx-azure/tee-self-attestation-test.manifest.toml new file mode 100644 index 0000000..0bf0f0a --- /dev/null +++ b/packages/container-self-attestation-test-sgx-azure/tee-self-attestation-test.manifest.toml @@ -0,0 +1,56 @@ +libos.entrypoint = "{{ entrypoint }}" + +[loader] +argv = ["{{ entrypoint }}"] +entrypoint = "file:{{ gramine.libos }}" +log_level = "{{ log_level }}" + +[loader.env] +### DEBUG ### +RUST_BACKTRACE = "1" +RUST_LOG = "warning" + +### Fixed values ### +LD_LIBRARY_PATH = "{{ gramine.runtimedir() }}:/lib" +SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt" +PATH = "/bin" +HOME = "/app" + +MALLOC_ARENA_MAX = "1" +AZDCAP_DEBUG_LOG_LEVEL = "ignore" +AZDCAP_COLLATERAL_VERSION = "v4" + +[fs] +root.uri = "file:/" +start_dir = "/app" +mounts = [ + { type = "tmpfs", path = "/var/tmp" }, + { type = "tmpfs", path = "/tmp" }, + { type = "tmpfs", path = "/app/.dcap-qcnl" }, + { type = "tmpfs", path = "/app/.az-dcap-client" }, +] + +[sgx] +trusted_files = [ + "file:/app/", + "file:/bin/", + "file:/etc/gai.conf", + "file:/etc/ssl/certs/ca-bundle.crt", + "file:/lib/", + "file:/nix/", + "file:{{ gramine.libos }}", + "file:{{ gramine.runtimedir() }}/", +] +remote_attestation = "dcap" +max_threads = 64 +edmm_enable = false +## max enclave size +enclave_size = "2G" + +[sys] +enable_extra_runtime_domain_names_conf = true +enable_sigterm_injection = true + +# possible tweak option, if problems with mio +# currently mio is compiled with `mio_unsupported_force_waker_pipe` +# insecure__allow_eventfd = true diff --git a/packages/container-self-attestation-test-sgx-dcap/Dockerfile b/packages/container-self-attestation-test-sgx-dcap/Dockerfile new file mode 100644 index 0000000..a8d879b --- /dev/null +++ b/packages/container-self-attestation-test-sgx-dcap/Dockerfile @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Matter Labs + +FROM teepot-self-attestation-test-sgx-dcap:base + +WORKDIR /app + +COPY packages/container-vault-sgx-azure/test-enclave-key.pem /tmp/ +COPY assets/sgx_default_qcnl.conf.json /etc/sgx_default_qcnl.conf + +RUN set -eux; \ + touch -r /nix/store /etc/sgx_default_qcnl.conf; \ + gramine-manifest -Darch_libdir=/lib/x86_64-linux-gnu \ + -Dentrypoint=$(readlink /bin/tee-self-attestation-test) \ + -Dexecdir=/bin \ + -Dlog_level=error \ + tee-self-attestation-test.manifest.toml tee-self-attestation-test.manifest; \ + gramine-sgx-sign --manifest tee-self-attestation-test.manifest --output tee-self-attestation-test.manifest.sgx --key /tmp/test-enclave-key.pem; \ + rm /tmp/test-enclave-key.pem + +EXPOSE 8443 + +ENTRYPOINT ["/bin/sh", "-c"] +ENV SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt +CMD [ "restart-aesmd >&2; exec gramine-sgx tee-self-attestation-test" ] diff --git a/packages/container-self-attestation-test-sgx-dcap/default.nix b/packages/container-self-attestation-test-sgx-dcap/default.nix new file mode 100644 index 0000000..1d77364 --- /dev/null +++ b/packages/container-self-attestation-test-sgx-dcap/default.nix @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Matter Labs +{ pkgs +, vat +, nixsgx +, curl +, teepot +, bash +, coreutils +, openssl +}: +let manifest = ./tee-self-attestation-test.manifest.toml; +in pkgs.dockerTools.buildLayeredImage { + name = "teepot-self-attestation-test-sgx-dcap"; + tag = "base"; + + config.Entrypoint = [ "/bin/sh" "-c" ]; + + contents = pkgs.buildEnv { + name = "image-root"; + + paths = with pkgs.dockerTools; with nixsgx;[ + bash + coreutils + openssl.out + curl.out + teepot.teepot.tee_self_attestation_test + gramine + restart-aesmd + sgx-dcap.quote_verify + sgx-dcap.default_qpl + sgx-psw + usrBinEnv + binSh + caCertificates + fakeNss + ]; + pathsToLink = [ "/bin" "/lib" "/etc" "/share" "/app" ]; + postBuild = '' + mkdir -p $out/{app,etc} + mkdir -p $out/app/{.dcap-qcnl,.az-dcap-client} + mkdir -p $out/var/run + mkdir -p $out/${nixsgx.sgx-psw.out}/aesm/ + ln -s ${curl.out}/lib/libcurl.so $out/${nixsgx.sgx-psw.out}/aesm/ + cp ${manifest} $out/app/tee-self-attestation-test.manifest.toml + printf "precedence ::ffff:0:0/96 100\n" > $out/etc/gai.conf + ''; + }; +} diff --git a/packages/container-self-attestation-test-sgx-dcap/tee-self-attestation-test.manifest.toml b/packages/container-self-attestation-test-sgx-dcap/tee-self-attestation-test.manifest.toml new file mode 100644 index 0000000..4ee2953 --- /dev/null +++ b/packages/container-self-attestation-test-sgx-dcap/tee-self-attestation-test.manifest.toml @@ -0,0 +1,57 @@ +libos.entrypoint = "{{ entrypoint }}" + +[loader] +argv = ["{{ entrypoint }}"] +entrypoint = "file:{{ gramine.libos }}" +log_level = "{{ log_level }}" + +[loader.env] +### DEBUG ### +RUST_BACKTRACE = "1" +RUST_LOG = "warning" + +### Fixed values ### +LD_LIBRARY_PATH = "{{ gramine.runtimedir() }}:/lib" +SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt" +PATH = "/bin" +HOME = "/app" + +MALLOC_ARENA_MAX = "1" +AZDCAP_DEBUG_LOG_LEVEL = "ignore" +AZDCAP_COLLATERAL_VERSION = "v4" + +[fs] +root.uri = "file:/" +start_dir = "/app" +mounts = [ + { type = "tmpfs", path = "/var/tmp" }, + { type = "tmpfs", path = "/tmp" }, + { type = "tmpfs", path = "/app/.dcap-qcnl" }, + { type = "tmpfs", path = "/app/.az-dcap-client" }, +] + +[sgx] +trusted_files = [ + "file:/app/", + "file:/bin/", + "file:/etc/gai.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/ssl/certs/ca-bundle.crt", + "file:/lib/", + "file:/nix/", + "file:{{ gramine.libos }}", + "file:{{ gramine.runtimedir() }}/", +] +remote_attestation = "dcap" +max_threads = 64 +edmm_enable = false +## max enclave size +enclave_size = "2G" + +[sys] +enable_extra_runtime_domain_names_conf = true +enable_sigterm_injection = true + +# possible tweak option, if problems with mio +# currently mio is compiled with `mio_unsupported_force_waker_pipe` +# insecure__allow_eventfd = true diff --git a/packages/container-verify-attestation-sgx-azure/default.nix b/packages/container-verify-attestation-sgx-azure/default.nix new file mode 100644 index 0000000..7b601cf --- /dev/null +++ b/packages/container-verify-attestation-sgx-azure/default.nix @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Matter Labs +{ lib +, dockerTools +, buildEnv +, teepot +, openssl +, curl +, nixsgx +, ... +}: +dockerTools.buildLayeredImage { + name = "verify-attestation-sgx-azure"; + tag = "latest"; + + config.Cmd = [ "${teepot.teepot.verify_attestation}/bin/verify-attestation" ]; + config.Env = [ + "LD_LIBRARY_PATH=/lib" +"AZDCAP_DEBUG_LOG_LEVEL=ignore" +"AZDCAP_COLLATERAL_VERSION=v4" + ]; + contents = buildEnv { + name = "image-root"; + + paths = with dockerTools; with nixsgx;[ + openssl.out + curl.out + azure-dcap-client + sgx-dcap.quote_verify + teepot.teepot.verify_attestation + usrBinEnv + binSh + caCertificates + fakeNss + ]; + pathsToLink = [ "/bin" "/lib" "/etc" "/share" ]; + }; +} diff --git a/packages/container-verify-attestation-sgx-dcap/default.nix b/packages/container-verify-attestation-sgx-dcap/default.nix new file mode 100644 index 0000000..f4bf0b1 --- /dev/null +++ b/packages/container-verify-attestation-sgx-dcap/default.nix @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2024 Matter Labs +{ lib +, dockerTools +, buildEnv +, teepot +, openssl +, curl +, nixsgx +, ... +}: +dockerTools.buildLayeredImage { + name = "verify-attestation-sgx-dcap"; + tag = "latest"; + + config.Cmd = [ "${teepot.teepot.verify_attestation}/bin/verify-attestation" ]; + config.Env = [ "LD_LIBRARY_PATH=/lib" ]; + contents = buildEnv { + name = "image-root"; + + paths = with dockerTools; with nixsgx;[ + openssl.out + curl.out + sgx-dcap.quote_verify + sgx-dcap.default_qpl + teepot.teepot.verify_attestation + usrBinEnv + binSh + caCertificates + fakeNss + ]; + pathsToLink = [ "/bin" "/lib" "/etc" "/share" ]; + }; +} diff --git a/packages/container-verify-attestation/default.nix b/packages/container-verify-attestation/default.nix deleted file mode 100644 index 6fb7eed..0000000 --- a/packages/container-verify-attestation/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2024 Matter Labs -{ lib -, dockerTools -, teepot -, ... -}: -dockerTools.buildImage { - name = "verify-attestation"; - tag = "latest"; - - copyToRoot = [ - teepot.teepot.verify_attestation - ]; - config = { Cmd = [ "${teepot.teepot.verify_attestation}/bin/verify-attestation" ]; }; -}