Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Remote Attestation Example

Introduction

The process consists of several parts:

  • provisioning
  • gathering measurements
  • feeding measurements to veraison and realm verifier
  • running realm for verification purposes
  • running verification services (veraison/realm verifier)
  • verification itself

It is best and even sometimes required that all the required repos are placed in one directory. I’ll call it CCA and it will be referred throughout this file.

The following repos will be used:

Preparation

Only the Islet repository should be checked manually:

CCA/islet

Now run make inside the CCA/islet/examples/veraison directory. This compiles some tools that will be used for this demo and places them inside proper directories. It also copies the root-ca.crt used by realm-application.

CCA/islet/examples/veraison $ make clean   # optional, will cause full rebuild
CCA/islet/examples/veraison $ make

The files installed are:

  • root-ca.crt copied to CCA/islet/out/shared
  • rsictl installed in CCA/islet/out/shared/bin (AARCH64) and CCA/islet/examples/veraison/bin (X86_64)
  • realm-application installed in CCA/islet/out/shared/bin
  • rocli installed in CCA/islet/examples/veraison/bin
  • reliant-party installed in CCA/islet/examples/veraison/bin

Provisioning

This is emulated by generating CPAK public key using one of camellia-hes utilities:

CCA/islet/hes/cpak-generator $ cargo run

This will by default generate a CPAK using dummy GUK and dummy BL2 hash files from CCA/islet/hes/res directory and save both key binary and PEM format respectively as:

CCA/islet/hes/out/cpak_public.bin
CCA/islet/hes/out/cpak_public.pem

Gathering measurements

There are 2 things we need to measure here. Platform and realm.

Platform measurement

The platform measurement is done by getting the whole CCA token. Platform measurements are saved there.

This is performed by some specifically prepared realm (e.g. one provided by CCA/islet/scripts/qemu-cca). To do this do the following:

CCA/islet $ ./scripts/init.sh
CCA/islet $ ./scripts/qemu-cca --normal-world=linux-net --realm=linux --rmm=islet --hes --rmm-log-level info

The first command will initialize the scripts and download all required components. The second command will build the platform and the realm and run the QEMU emulator and the HES application.

When run under X environment terminals should open named as following:

  • Firmware
  • Host
  • Realm

We will be exclusively using the Host one.

When the QEMU linux is booted we need to run the realm:

$ ./launch-realm.sh

This will take some time. Wait until you have a realm loaded. Then load RSI module and get the token:

Welcome to Buildroot
buildroot login: root

# cd /shared
shared # insmod rsi.ko
shared # ./bin/rsictl attest -o token.bin

For the token its challenge value will be randomized, but in here it doesn’t matter. Now we can kill the QEMU (ctrl-c on the QEMU terminal).

The generated token is saved as the following file:

CCA/islet/out/shared/token.bin

Realm measurement

Realm measurement is done by generating a json file containing realm information that will be fed to realm verifier.

Using kvmtool-rim-measurer

Caution

This tool needs an update for v1.0-rel0, use the alternative method below for now

Warning

This section needs to be simplified

This is performed by a small helper program called kvmtool-rim-measurer. It basically runs a modified lkvm tool that calculates and displays the RIM value. The process looks as follows:

  • generate/get the realm you want to use (for now generated by qemu-cca script, those files can be taken from CCA/islet/out/shared, these files include the linux kernel image linux.realm, initrd file rootfs-realm.cpio.gz and the shell script used for launching the realm launch-realm.sh)
  • Build the kvmtool-rim-measurer tool according to the description https://github.com/islet-project/3rd-kvmtool/blob/kvmtool-rim-measurer/eac5/BUILD-RIM-MEASURER
  • Create a dedicated directory for realm files (e.g. CCA/islet/out/rim-extractor) and copy all the realm files we want to measure to that folder
  • copy the resulting lkvm-rim-measurer to the CCA/islet/out/rim-extractor folder
  • substitute lkvm to lkvm-rim-measurer in the CCA/islet/out/rim-extractor/launch-realm.sh script
  • get into the CCA/islet/out/rim-extractor folder and run the launch-realm.sh script
  • The lkvm-rim-measurer will display the resulting RIM (e.g. RIM: F58AF6D6A022F113627B1E0B1E0D9B9A1BFB460207AC29721E84BCEF4B4F5CE08351684444BC11CF329D1D4C807BB621807916C2DF4F56B7326E8D16692546A8)

Alternatively: extract the RIM from the token file

Display the token using rsictl command:

CCA/islet/examples/veraison $ ./bin/rsictl verify -i ../../out/shared/token.bin | grep 'Realm initial measurement'
Realm initial measurement      (#44238) = [ace992744cb08283a2c5a31785b2d307a7936825751f9affc64ea37b02d9effb]

RIM value is between [] characters.

Create a refence measurement values file

Create a reference.json file using the commands below (replace the PASTE_THE_OBTAINED_RIM_HEX_STRING_HERE with the RIM obtained from one of the previous steps):

export RIM="PASTE_THE_OBTAINED_RIM_HEX_STRING_HERE"

cat > reference.json << EOF
{
    "version": "0.1",
    "issuer": {
        "name": "Samsung",
        "url": "https://cca-realms.samsung.com/"
    },
    "realm": {
        "uuid": "f7e3e8ef-e0cc-4098-98f8-3a12436da040",
        "name": "Data Processing Service",
        "version": "1.0.0",
        "release-timestamp": "2024-09-09T05:21:31Z",
        "attestation-protocol": "HTTPS/RA-TLSv1.0",
        "port": 8088,
        "reference-values": {
            "rim": "$RIM",
            "rems": [
                [
                    "0000000000000000000000000000000000000000000000000000000000000000",
                    "0000000000000000000000000000000000000000000000000000000000000000",
                    "0000000000000000000000000000000000000000000000000000000000000000",
                    "0000000000000000000000000000000000000000000000000000000000000000"
                ]
            ],
            "hash-algo": "sha-256"
        }
    }
}
EOF

The resulting json will be saved as the following file:

CCA/islet/examples/veraison/reference.json

Caveat: only RIM is supported for now, the REMs are placeholders.

Provisioning/Measurement summary

Those 2 processes should end with the following things

  • Prepared realm that won’t be modified anymore: linux.realm rootfs-realm.cpio.gz launch-realm.sh For now we use the one generated by qemu-cca
  • Public CPAK key: cpak_public.bin cpak_public.pem
  • Platform measurement: token.bin
  • Realm measurement: reference.json

CPAK keys, token and measurement files should be sent to verification services using a safe communication channel.

Running realm for verification purposes

This is done in almost the same way we run realm to get the token.

Run the QEMU with HES and network this time. Use the –run-only param from now on not to regenerate the realm anymore so our measurements won’t get stale:

CCA/islet $ ./scripts/qemu-cca --normal-world=linux-net --realm=linux --rmm=islet --hes --rmm-log-level info --run-only

When QEMU Linux is booted run the realm:

# ./launch-realm.sh net

Inside the realm you need to do the following:

  • configure the network
  • load the RSI module
  • set the date for the certificates to work properly

This is how it looks:

Welcome to Buildroot
buildroot login: root

# cd /shared
shared # ./set-realm-ip.sh
shared # insmod rsi.ko
shared # date -s "2025-09-12 12:00"

Running and provisioning verification services (Veraison, realm-verifier)

To bootstrap the Veraison services use the CCA/islet/examples/veraison/bootstrap.sh:

CCA/islet/examples/veraison $ ./bootstrap.sh

In details, it does a couple of things:

  • Cloning the https://github.com/veraison/services repo to CCA/islet/exmaples/veraison/services .
  • Applies veraison-gopls-version.patch to fix compilation and veraison-no-auth.patch to disable endpoints authentication.
  • Builds Docker containers by running CCA/islet/exmaples/veraison/services/deployments/docker/Makefile.
  • Start Veraison by running veraison start.
  • Inserts the ./accept-all.rego policy which makes Veraison accept all implementation IDs etc. (normally you are supposed to create a set of rules checking various parts of the attestation token).

To get access to the veraison cli interface source:

  • CCA/islet/exmaples/veraison $ source services/deployments/docker/env.zsh for zsh,
  • CCA/islet/exmaples/veraison $ source services/deployments/docker/env.bash for bash.

Check if all 5 veraison services are running:

$ veraison status
vts: running
provisioning: running
verification: running
management: running
keycloak: running

And run provisioning of token and CPAK in PEM format:

CCA/islet/examples/veraison/provisioning $ ./run.sh -t <path/to/token.bin> -c <path/to/cpak_public.pem>

This will provision a reference token and public CPAK to allow Veraison verification.

It’s possible to see current values stored in Veraison:

$ veraison stores

Run reliant-party, which is provisioned with reference.json and acts as Reliant Party with communication to realm and Veraison services (this binary takes several parameters, most should not be of any concern apart from passing latest reference values in reference.json):

CCA/islet/examples/veraison $ RUST_LOG=info ./bin/reliant-party -r <path/to/reference.json>

If needed, ‘-b’ option can be used to pass different network interface binding (the default is 0.0.0.0:1337):

CCA/islet/examples/veraison $ RUST_LOG=info ./bin/reliant-party -r <path/to/reference.json> -b <LOCAL_IP:PORT>

Reliant-party awaits on given IP:PORT for communication from Realm and utilizes our ratls Rust library and realm-verifier library (for reference.json reference values verification) to verify client CCA token.

Verification itself

On the realm side (the one we already run) just trigger the verification process. This is done using realm-application (CCA/islet/examples/veraison/realm-application). It will initialize RATLS connection to verification service by performing the necessary steps:

  • receive challenge value from verification service
  • request the token from RMM/TF-A/HES using the challenge
  • send the received token to verification service
  • establish safe connection if verification services agrees to do so

This is done with the following command on the realm (use 192.168.10.1:1337 when run on the same machine or any other <SERVER_IP:PORT> when needed)

shared # RUST_LOG=info ./bin/realm-application -r root-ca.crt -u 192.168.10.1:1337

That command will take some time as computation inside Realm can be slow and it does asymmetric cryptography (RSA key generation).

Verification success

When verification succeeds, both realm-application and realm-verifier should not output any errors.

With the info log level (as set above) realm client should report successful socket write with ‘GIT’ message and verifying server should output that message.