This setup shows step-by-step how to install the tools, generate the metadata describing the platform and run and test the tools. It was tested on Ubuntu 22.04 LTS.
Install utilities for building and setting up the PKI:
sudo apt install moreutils golang-cfssl build-essential
Install tpm-pcr-tools for calculating/parsing TPM PCR values for TPM-based attestation:
sudo apt install -y build-essential zlib1g-dev libssl-dev
git clone https://github.com/Fraunhofer-AISEC/tpm-pcr-tools.git
cd tpm-pcr-tools
make
sudo make install # Or launch from individual folders
Install the Intel SGX DCAP libraries and utilities according to the Intel manual.
Install the EGo framework.
# Clone the CMC repo
git clone https://github.com/Fraunhofer-AISEC/cmc
# Build CMC
cd cmc
go build ./...
# Install CMC $GOPATH/bin (export PATH=$PATH:$HOME/go/bin -> .profile/.bashrc)
go install ./...
Do this outside the repository:
mkdir -p cmc-data
For the example, it is sufficient to copy the templates. For information on how to adjust the metadata, see Generating Metadata and Setup Alternatives
cp -r cmc/example-setup/* cmc-data
Generate a PKI suitable for your needs. A minimal PKI can be setup as follows:
# Generate example PKI
./cmc-data/setup-pki -i ./cmc-data -o ./cmc-data/pki
For a more complex PKI, have a look at the IDS-Setup.
The example setup (folder cmc/example-setup
) contains templates for the required metadata files
in JSON. The attributes of these files can be adjusted according to individual requirements:
- rtm.manifest.json: Contains information about the Root of Trust for Measurements, which usually comprises the reference values (hashes) for BIOS/UEFI, bootloader and other early boot components
- os.manifest.json: Contains the operating system reference values and information
- app.manifest.json: Contains the reference values for an app on the system
- company.description.json: Optional, metadata describing the operater of the computing platform
- device.description.json: Metadata describing the overall platform, contains links to RTM Manifest, OS Manifest
- app.description.json: Metadata describing an application, links to an App Manifest. Must be
embedded in to the
appDescriptions
property of the device description. - device.config.json: Signed local device configuration, contains e.g. the parameters for the Certificate Signing Requests for the attestation and identity keys
The attestation report can be serialized to JSON and signed via JSON Web signatures (JWS), or to CBOR and signed via CBOR Object Signing and Encryption (COSE). This must be specified in the configuration of the cmcd (see CMCD Configuration) and the provisioning server (see Provisioning Server Configuration)
As CBOR is a binary serialization format, the serialized data is not human-readable. Therefore, the metadata templates are always in JSON. A converter tool is provided to convert the metadata files to CBOR before signing them. To convert a metadata file from JSON to CBOR:
# Convert JSON to CBOR using the converter-tool
cmc/tools/cmc-converter/cmc-converter -in <input-file>.json -out <output-file.cbor> -inform json -outform cbor
The self-contained attestation reports (see Architecture) contain signed reference-values that describe the legitimate software that is expected to be running on the platform. The trust in the measurements comes from hardware-based measurement technologies, such as TPMs or Confidential Computing technologies. The reference values for the proving platform must be generated based on the used technology.
The reference values can either be parsed once on a good reference platform in a secure environment, or they can be calculated based on the built software artifacts of a computing platform (e.g., within a build-system such as Yocto or Buildroot). Tools for parsing and calculated are available as open source tpm-pcr-tools.
Parsing the reference values on a good reference platform and inserting them into the manifest
Parse the values of the RTM PCRs from the kernel's binary bios measurement log
sudo parse-srtm-pcrs -p 0,1,2,3,4,5,6,7 -f json
Then insert those values into the json referenceValues
array in the RTM manifest.
Parse the values of the OS PCRs from the kernel's binary bios measurement log:
sudo parse-srtm-pcrs -p 8,9,11,12,14,15 -f json
Then insert those values into the json referenceValues
array in the OS manifest.
For the host applications, if the kernel's Integrity Measurement Architecture (IMA) is activated:
sudo parse-ima-pcr
Then insert those values into the json referenceValues
array in an app manifest.
For OCI containers, currently the containerd
tool ctr
is supported with the custom cmc
runtime cmc/tools/containerd-shim-cmc-v1/containerd-shim-cmc-v1
:
sudo ctr run --runtime ${runtime} -t --rm docker.io/library/ubuntu:22.04 CMC_GENERATE_APP_MANIFEST
the reference values are generated at /tmp/container-refs
and must be put into an app manifest.
Calculating the reference values based on software artifacts
This currently only works for QEMU VMs with OVMF and a Linux kernel. it is recommended to use the parsing alternative.
Calculate the RTM Manifest reference values:
calculate-srtm-pcrs \
--format json \
--pcrs 0,1,2,3,6,7 \
--eventlog \
--kernel "linux-kernel.bzImage" \
--ovmf "OVMF.fd" \
--config "calculate-pcrs.cfg" \
Then insert those values into the json referenceValues
array in the RTM Manifest.
Calculate the OS Manifest reference values:
calculate-srtm-pcrs \
--kernel "linux-kernel.bzImage" \
--cmdline "linux-commandline" \
--ovmf "OVMF.fd" \
--format json \
--pcrs "4,5,8,9,11,12,13,14,15" \
--eventlog \
Then insert those values into the json referenceValues
array in the OS Manifest.
For the host applications, if the kernel's Integrity Measurement Architecture (IMA) is activated:
# In this case, use PCR10 and the IMA ima-ng template for all folders containing binaries and libs
sudo calculate-ima-pcr -t 10 -i ima-ng -p /usr/bin -p /usr/sbin -p /usr/lib
Then insert those values into an app manifest.
For OCI containers, the buildah
and umoci
tool can be used in combination with the custom
cmc/tools/measure-bundle/measure-bundle
tool can be used:
buildah pull ubuntu:22.04
buildah push ubuntu:22.04 oci-archive:myimage-oci.tar:latest
tar -xvf myimage-oci.tar
(cd image ; umoci unpack --rootless --image ./:latest bundle)
measure-bundle -config image/bundle/config.json" -rootfs image/bundle/rootfs)
Then, insert those reference values into an App Manifest.
tbd
tbd
The reference values for Intel SGX consist of a fingerprint of the Intel Root CA certificate, the TCB Info and QE Identity structures, the enclave product ID (ISV Prod ID), the security version of the enclave (ISVSVN), expected enclave attributes (e.g. DEBUG, Mode64Bit, etc.), a hash of the enclave measurement (MRENCLAVE) and a hash of the enclave signing key (MRSIGNER).
The Root CA certificate, TCB Info and QE Identity structures can be retrieved from the Intel API. ISV SVN and ISV Prod ID are assigned by the enclave author. The EGo framework sets these values to 1 by default.
The MRENCLAVE and MRSIGNER values for an enclave can be retrieved via the EGo CLI tool with the commands ego uniqueid $ENCLAVE_PROGRAM
and ego signerid $ENCLAVE_PROGRAM
.
This example uses JSON/JWS as serialization format. For different formats see Serialization Format
IN=cmc-data/metadata-raw
OUT=cmc-data/metadata-signed
KEY=cmc-data/pki/signing-cert-key.pem
CHAIN=cmc-data/pki/signing-cert.pem,cmc-data/pki/ca.pem
mkdir -p $OUT
cmc-signing-tool -in $IN/rtm.manifest.json -out $OUT/rtm.manifest.json -keys $KEY -x5cs $CHAIN
cmc-signing-tool -in $IN/os.manifest.json -out $OUT/os.manifest.json -keys $KEY -x5cs $CHAIN
cmc-signing-tool -in $IN/device.description.json -out $OUT/device.description.json -keys $KEY -x5cs $CHAIN
cmc-signing-tool -in $IN/device.config.json -out $OUT/device.config.json -keys $KEY -x5cs $CHAIN
Adjust the configuration files for the tools as required according to Configuration.
# Start the EST server that supplies the certificates and metadata for the cmcd
./estserver -config cmc-data/est-server-conf.json
# Build and run the cmcd
./cmcd -config cmc-data/cmcd-conf.json
# Run the testtool to retrieve an attestation report (stored in current folder unless otherwise specified)
./testtool -mode generate
# Run the testtool to verify the attestation report (stored in current folder unless otherwise specified)
./testtool -mode verify -ca cmc-data/pki/ca.pem
# Run an attested TLS server
./testtool -mode listen -addr 0.0.0.0:4443 -ca cmc-data/pki/ca.pem -mtls
# Run an attested TLS client estblishing a mutually attested TLS connection to the server
./testtool -mode dial -addr localhost:4443 -ca cmc-data/pki/ca.pem -mtls
# Run two attested HTTPS servers
./testtool -config testtool-config.json -addr 0.0.0.0:8081 -mode serve
# Perform multiple user-specified attested HTTPS requests to both servers. Each connection is
# attested, while multiple requests to the same server use the established attested TLS connections
./testtool \
-config ../../cmc-data/testtool-lib-config.json \
-addr https://localhost:8081/post,https://localhost:8082/post \
-mode request \
-method POST \
-data "hello from attested HTTPS client" \
-header "Content-Type: text/plain"