diff --git a/.github/workflows/lib-build.yaml b/.github/workflows/lib-build.yaml index cd25d753c..070f53dd8 100644 --- a/.github/workflows/lib-build.yaml +++ b/.github/workflows/lib-build.yaml @@ -35,6 +35,8 @@ jobs: - openssl-qat-engine - sgx-sdk-demo - sgx-aesmd-demo + - sgx-dcap-infra + - sgx-pccs - dsa-dpdk-dmadevtest - intel-npu-demo builder: [buildah, docker] diff --git a/demo/sgx-dcap-infra/Dockerfile b/demo/sgx-dcap-infra/Dockerfile new file mode 100644 index 000000000..2fc416319 --- /dev/null +++ b/demo/sgx-dcap-infra/Dockerfile @@ -0,0 +1,61 @@ +FROM ubuntu:24.04 AS builder + +RUN apt-get update && \ + env DEBIAN_FRONTEND=noninteractive apt-get install -y \ + build-essential \ + curl \ + libcurl4-openssl-dev + +WORKDIR /opt/intel + +ARG SGX_SDK_URL=https://download.01.org/intel-sgx/sgx-linux/2.26/distro/ubuntu24.04-server/sgx_linux_x64_sdk_2.26.100.0.bin + +RUN curl -sSLfO ${SGX_SDK_URL} \ + && export SGX_SDK_INSTALLER=$(basename $SGX_SDK_URL) \ + && chmod +x $SGX_SDK_INSTALLER \ + && echo "yes" | ./$SGX_SDK_INSTALLER \ + && rm $SGX_SDK_INSTALLER + +ARG DCAP_VERSION=DCAP_1.23 +ARG DCAP_TARBALL_SHA256="c4567e7bc0a2f0dbb70fa2625a9af492e00b96e83d07fa69b9f4f304a9992495" + +RUN curl -sSLfO https://github.com/intel/SGXDataCenterAttestationPrimitives/archive/$DCAP_VERSION.tar.gz && \ + echo "$DCAP_TARBALL_SHA256 $DCAP_VERSION.tar.gz" | sha256sum -c - && \ + tar xzf $DCAP_VERSION.tar.gz && mv SGXDataCenterAttestationPrimitives* SGXDataCenterAttestationPrimitives + +WORKDIR SGXDataCenterAttestationPrimitives/tools/PCKRetrievalTool + +RUN sed -e 's:sys/firmware/efi:run:g' -i App/utility.cpp \ + && make + +FROM ubuntu:24.04 + +WORKDIR /opt/intel/sgx-pck-id-retrieval-tool/ +COPY --from=builder /opt/intel/SGXDataCenterAttestationPrimitives/tools/PCKRetrievalTool/PCKIDRetrievalTool . + +RUN ln -sf /lib/x86_64-linux-gnu/libsgx_id_enclave.signed.so.1 && \ + ln -sf /lib/x86_64-linux-gnu/libsgx_pce.signed.so.1 + +ARG SGX_SDK_VERSION=2_26_100 +RUN apt update && apt install -y curl gnupg \ + && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-sgx.gpg] https://download.01.org/intel-sgx/sgx_repo/ubuntu noble main" | \ + tee -a /etc/apt/sources.list.d/intel-sgx.list \ + && curl -s https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | \ + gpg --dearmor --output /usr/share/keyrings/intel-sgx.gpg \ + && curl -sFLf https://download.01.org/intel-sgx/sgx_repo/ubuntu/apt_preference_files/99sgx_${SGXSDK_VERSION}_noble_custom_version.cfg | \ + tee -a /etc/apt/preferences.d/99sgx_sdk \ + && apt update \ + && apt install -y --no-install-recommends \ + libcurl4 \ + tdx-qgs \ + libsgx-ae-pce \ + libsgx-ae-id-enclave \ + libsgx-ra-uefi \ + libsgx-dcap-default-qpl + +# BUG: "qgs -p=0" gets overriden by the config file making the parameter useless +RUN sed -e 's/\(^port =\).*/\1 0/g' -i /etc/qgs.conf + +COPY dcap-registration-flow /usr/bin + +ENTRYPOINT ["/opt/intel/tdx-qgs/qgs", "--no-daemon", "-p=0"] diff --git a/demo/sgx-dcap-infra/dcap-registration-flow b/demo/sgx-dcap-infra/dcap-registration-flow new file mode 100755 index 000000000..4271a60b0 --- /dev/null +++ b/demo/sgx-dcap-infra/dcap-registration-flow @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -u + +if [ ! -x "${PWD}"/PCKIDRetrievalTool ]; then + echo "dcap-registration-flow: PCKIDRetrievalTool must be in the workingDir and executable" + exit 1 +fi + +echo "Waiting for the PCCS to be ready ..." + +if ! curl --retry 20 --retry-delay 30 -k ${PCCS_URL}/sgx/certification/v4/rootcacrl &> /dev/null; then + echo "ERROR: PCCS pod didn't become ready after 20 minutes" + exit 1 +fi + +echo "PCCS is online, proceeding ..." + +ARGS="-user_token ${USER_TOKEN} -url ${PCCS_URL} -use_secure_cert ${SECURE_CERT}" + +echo "Calling PCKIDRetrievalTool ..." + +./PCKIDRetrievalTool ${ARGS} + +sleep infinity diff --git a/demo/sgx-pccs/Dockerfile b/demo/sgx-pccs/Dockerfile new file mode 100644 index 000000000..cc497c27d --- /dev/null +++ b/demo/sgx-pccs/Dockerfile @@ -0,0 +1,32 @@ +FROM registry.access.redhat.com/ubi9/nodejs-20:latest AS builder + +USER root + +RUN dnf install -y \ + file \ + jq \ + zip + +ARG DCAP_VERSION=DCAP_1.23 + +RUN git clone -b ${DCAP_VERSION} --depth 1 --recurse-submodules https://github.com/intel/SGXDataCenterAttestationPrimitives.git + +WORKDIR SGXDataCenterAttestationPrimitives/tools/PCKCertSelection/ +RUN mkdir -p ../../prebuilt/openssl/inc \ + && mkdir -p ../../QuoteGeneration/pccs/lib \ + && make \ + && cp ./out/libPCKCertSelection.so ../../QuoteGeneration/pccs/lib + +WORKDIR /opt/app-root/src/SGXDataCenterAttestationPrimitives/QuoteGeneration/pccs +RUN npm config set engine-strict true \ + && npm install \ + && npm audit fix + +FROM registry.access.redhat.com/ubi9/nodejs-20-minimal:latest + +WORKDIR intel/pccs +COPY --from=builder --chown=1001:users /opt/app-root/src/SGXDataCenterAttestationPrimitives/QuoteGeneration/pccs . +COPY --chown=1001:users default.json config/ +COPY --chown=1001:users custom-environment-variables.json config/ + +ENTRYPOINT ["/usr/bin/node", "pccs_server.js"] diff --git a/demo/sgx-pccs/custom-environment-variables.json b/demo/sgx-pccs/custom-environment-variables.json new file mode 100644 index 000000000..889fe2ca7 --- /dev/null +++ b/demo/sgx-pccs/custom-environment-variables.json @@ -0,0 +1,7 @@ +{ + "ApiKey": "PCS_API_KEY", + "proxy": "CLUSTER_HTTPS_PROXY", + "UserTokenHash": "PCCS_USER_TOKEN_HASH", + "AdminTokenHash": "PCCS_ADMIN_TOKEN_HASH", + "CachingFillMode": "PCCS_FILL_MODE" +} diff --git a/demo/sgx-pccs/default.json b/demo/sgx-pccs/default.json new file mode 100644 index 000000000..53cd5aff8 --- /dev/null +++ b/demo/sgx-pccs/default.json @@ -0,0 +1,34 @@ +{ + "HTTPS_PORT": 8042, + "hosts": "0.0.0.0", + "uri": "https://api.trustedservices.intel.com/sgx/certification/v4/", + "ApiKey": "", + "proxy": "", + "RefreshSchedule": "0 0 1 * * *", + "UserTokenHash": "", + "AdminTokenHash": "", + "CachingFillMode": "LAZY", + "OPENSSL_FIPS_MODE": false, + "LogLevel": "info", + "DB_CONFIG": "sqlite", + "sqlite": { + "database": "database", + "username": "username", + "password": "password", + "options": { + "host": "localhost", + "dialect": "sqlite", + "pool": { + "max": 5, + "min": 0, + "acquire": 30000, + "idle": 10000 + }, + "define": { + "freezeTableName": true + }, + "logging": true, + "storage": "/run/pccs/pckcache.db" + } + } +} diff --git a/deployments/sgx_dcap/base/kustomization.yaml b/deployments/sgx_dcap/base/kustomization.yaml new file mode 100644 index 000000000..7ece87260 --- /dev/null +++ b/deployments/sgx_dcap/base/kustomization.yaml @@ -0,0 +1,11 @@ +resources: +- node-services.yaml +generatorOptions: + disableNameSuffixHash: true + +# required .env.pccs-credentials keys: +# USER_TOKEN= +secretGenerator: +- name: pccs-credentials + envs: + - .env.pccs-credentials diff --git a/deployments/sgx_dcap/base/node-services.yaml b/deployments/sgx_dcap/base/node-services.yaml new file mode 100644 index 000000000..d6460e4fa --- /dev/null +++ b/deployments/sgx_dcap/base/node-services.yaml @@ -0,0 +1,90 @@ +# TODO +# cert-manager / service-ca certificates +# CURL_CA_BUNDLE once ^ is available +# NFD (TDX) nodeSelector +# cpu and memory resources/limits +# split service name and port (PCCS URL) +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: intel-dcap-node-infra +spec: + selector: + matchLabels: + app: dcap-node-infra + template: + metadata: + annotations: + qcnl-conf: '{"pccs_url": "https://pccs-service:8042/sgx/certification/v4/", "use_secure_cert": false, "pck_cache_expire_hours": 168}' + labels: + app: dcap-node-infra + pccs-secure-cert: 'false' + spec: + automountServiceAccountToken: false + initContainers: + - name: platform-registration + image: intel/sgx-dcap-infra:devel + restartPolicy: Always + workingDir: "/opt/intel/sgx-pck-id-retrieval-tool/" + command: ['/usr/bin/dcap-registration-flow'] + env: + - name: PCCS_URL + value: "https://pccs-service:8042" + - name: SECURE_CERT + valueFrom: + fieldRef: + fieldPath: metadata.labels['pccs-secure-cert'] + envFrom: + - secretRef: + name: pccs-credentials + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + add: + - LINUX_IMMUTABLE + resources: + limits: + sgx.intel.com/registration: 1 + containers: + - name: tdx-qgs + image: intel/sgx-dcap-infra:devel + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + resources: + limits: + sgx.intel.com/qe: 1 + imagePullPolicy: IfNotPresent + env: + - name: QCNL_CONF_PATH + value: "/run/dcap/qcnl_conf" + - name: XDG_CACHE_HOME + value: "/run/dcap/cache" + volumeMounts: + - name: dcap-qcnl-cache + mountPath: /run/dcap/cache + - name: qgs-socket + mountPath: /var/run/tdx-qgs + - name: qcnl-config + mountPath: /run/dcap/ + readOnly: true + volumes: + - name: dcap-qcnl-cache + emptyDir: + sizeLimit: 50Mi + - name: qgs-socket + hostPath: + path: /var/run/tdx-qgs + type: DirectoryOrCreate + - name: qcnl-config + downwardAPI: + items: + - path: "qcnl_conf" + fieldRef: + fieldPath: metadata.annotations['qcnl-conf'] diff --git a/deployments/sgx_dcap/kustomization.yaml b/deployments/sgx_dcap/kustomization.yaml new file mode 100644 index 000000000..715671aac --- /dev/null +++ b/deployments/sgx_dcap/kustomization.yaml @@ -0,0 +1,3 @@ +resources: + - base + - pccs diff --git a/deployments/sgx_dcap/pccs/kustomization.yaml b/deployments/sgx_dcap/pccs/kustomization.yaml new file mode 100644 index 000000000..22c9426a8 --- /dev/null +++ b/deployments/sgx_dcap/pccs/kustomization.yaml @@ -0,0 +1,25 @@ +resources: +- pccs.yaml +- service.yaml +generatorOptions: + disableNameSuffixHash: true + +# self-signed TLS certs for pccs-tls: +# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout private.pem -out file.crt -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" +# token hashesh follow (with 'hellworld' changed to the desired secret tokens): +# echo -n helloworld | sha512sum | tr -d '[:space:]-' +# where helloworld is then used as the USER_TOKEN in intel-dcap-node-infra deployment: +# +# required .env.pccs-tokens keys: +# PCS_API_KEY= +# PCCS_USER_TOKEN_HASH= +# PCCS_ADMIN_TOKEN_HASH= +secretGenerator: +- name: pccs-tokens + envs: + - .env.pccs-tokens +- name: pccs-tls + type: "kubernetes.io/tls" + files: + - tls.key=private.pem + - tls.crt=file.crt diff --git a/deployments/sgx_dcap/pccs/pccs.yaml b/deployments/sgx_dcap/pccs/pccs.yaml new file mode 100644 index 000000000..aa98017b1 --- /dev/null +++ b/deployments/sgx_dcap/pccs/pccs.yaml @@ -0,0 +1,60 @@ +# TODO +# cert-manager / service-ca certificates +# add PCCS nodeSelector +# cpu and memory resources/limits +# make HTTPS_PORT configurable via env +# fix proxy setting label +apiVersion: apps/v1 +kind: Deployment +metadata: + name: intel-dcap-pccs +spec: + replicas: 1 + selector: + matchLabels: + app: pccs + template: + metadata: + labels: + app: pccs + trustedservices.intel.com/cache: pccs + caching-mode: REQ + cluster-proxy-url: "" + spec: + containers: + - name: pccs + image: intel/sgx-pccs:devel + ports: + - containerPort: 8042 + name: pccs-port + volumeMounts: + - name: pccs-cache + mountPath: /run/pccs + - name: pccs-tls + mountPath: /opt/app-root/src/intel/pccs/ssl_key + readOnly: true + env: + - name: PCCS_FILL_MODE + valueFrom: + fieldRef: + fieldPath: metadata.labels['caching-mode'] + - name: CLUSTER_HTTPS_PROXY + #valueFrom: + # fieldRef: + # fieldPath: metadata.labels['cluster-proxy-url'] + value: "" + envFrom: + - secretRef: + name: pccs-tokens + volumes: + - name: pccs-cache + emptyDir: + sizeLimit: 50Mi + - name: pccs-tls + secret: + secretName: pccs-tls + items: + - key: tls.key + path: private.pem + - key: tls.crt + path: file.crt diff --git a/deployments/sgx_dcap/pccs/service.yaml b/deployments/sgx_dcap/pccs/service.yaml new file mode 100644 index 000000000..4d1066b3c --- /dev/null +++ b/deployments/sgx_dcap/pccs/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: pccs-service +spec: + selector: + trustedservices.intel.com/cache: pccs + ports: + - name: pccs + protocol: TCP + port: 8042 + targetPort: pccs-port diff --git a/deployments/sgx_plugin/overlays/dcap-infra-resources/add-args.yaml b/deployments/sgx_plugin/overlays/dcap-infra-resources/add-args.yaml new file mode 100644 index 000000000..df1cb334c --- /dev/null +++ b/deployments/sgx_plugin/overlays/dcap-infra-resources/add-args.yaml @@ -0,0 +1,11 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: intel-sgx-plugin +spec: + template: + spec: + containers: + - name: intel-sgx-plugin + args: + - "-dcap-infra-resources" diff --git a/deployments/sgx_plugin/overlays/dcap-infra-resources/kustomization.yaml b/deployments/sgx_plugin/overlays/dcap-infra-resources/kustomization.yaml new file mode 100644 index 000000000..f39afec02 --- /dev/null +++ b/deployments/sgx_plugin/overlays/dcap-infra-resources/kustomization.yaml @@ -0,0 +1,7 @@ +resources: + - ../../base +patches: + - path: add-args.yaml + target: + kind: DaemonSet +