From 28b3aeb67b03db81030e167fbe24f28a5e1a2a33 Mon Sep 17 00:00:00 2001 From: Anton Antonov Date: Thu, 28 May 2026 11:15:14 +0000 Subject: [PATCH] Add CCA BootSync Learning Path Signed-off-by: Anton Antonov --- .../cca-bootsync/_index.md | 67 +++ .../cca-bootsync/_next-steps.md | 8 + .../cca-bootsync/cca-bootsync.md | 21 + .../cca-bootsync/flow.md | 465 ++++++++++++++++++ 4 files changed, 561 insertions(+) create mode 100644 content/learning-paths/servers-and-cloud-computing/cca-bootsync/_index.md create mode 100644 content/learning-paths/servers-and-cloud-computing/cca-bootsync/_next-steps.md create mode 100644 content/learning-paths/servers-and-cloud-computing/cca-bootsync/cca-bootsync.md create mode 100644 content/learning-paths/servers-and-cloud-computing/cca-bootsync/flow.md diff --git a/content/learning-paths/servers-and-cloud-computing/cca-bootsync/_index.md b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/_index.md new file mode 100644 index 0000000000..edcbb29472 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/_index.md @@ -0,0 +1,67 @@ +--- +title: Arm CCA Boot Sync +description: Learn how to use Arm CCA Boot Sync while launching Arm CCA Realms on an FVP with RME support. + +minutes_to_complete: 60 + +who_is_this_for: This Learning Path is for developers who want to understand how to use Arm CCA Bootsync. + +learning_objectives: + - Gain an overview of Arm CCA Boot Sync and Boot Onjection Protocol. + - Understand how Arm CCA Boot Sync can be used for defining UEFI variables, enabling Secure Boot and share secure data with Arm CCA Realms. + - Lanch Arm CCA Realms with Secure Boot enabled and encrypted file system using an Armv9-A AEM Base Fixed Virtual Platform (FVP) with RME support. + +prerequisites: + - An AArch64 or x86_64 computer running Linux or macOS. Cloud-based instances can also be used; see the [Arm cloud service providers](/learning-paths/servers-and-cloud-computing/csp/) + - Completion of the [Run an application in a Realm using the Arm Confidential Compute Architecture (CCA)](/learning-paths/servers-and-cloud-computing/cca-container) Learning Path + +author: + - Anton Antonov + - Pareena Verma + +generate_summary_faq: true +rerun_summary: false +rerun_faqs: false + +### Tags +skilllevels: Advanced +subjects: Performance and Architecture +armips: + - Neoverse + - Cortex-A +operatingsystems: + - Linux + - macOS +tools_software_languages: + - FVP + - RME + - CCA + - Docker + - EDK2 + - Cryptsetup + +further_reading: + - resource: + title: Arm Confidential Compute Architecture + link: https://www.arm.com/architecture/security-features/arm-confidential-compute-architecture + type: website + - resource: + title: Arm Confidential Compute Architecture Open-Source enablement + link: https://www.youtube.com/watch?v=JXrNkYysuXw + type: video + - resource: + title: Learn the architecture - Realm Management Extension + link: https://developer.arm.com/documentation/den0126 + type: documentation + - resource: + title: Realm Management Monitor Specification + link: https://developer.arm.com/documentation/den0137/latest/ + type: documentation + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- + diff --git a/content/learning-paths/servers-and-cloud-computing/cca-bootsync/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/cca-bootsync/cca-bootsync.md b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/cca-bootsync.md new file mode 100644 index 0000000000..a0bc90e1e1 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/cca-bootsync.md @@ -0,0 +1,21 @@ +--- +# User change +title: "Overview of Arm CCA BootSync and Boot Injection protocol" + +weight: 2 # 1 is first, 2 is second, etc. + +# Do not modify these elements +layout: "learningpathall" +--- + +## Design overview + +TO_DO: Explain Boot Injection protocol and Arm CCA Boot Sync wokflow. + +For more details see: + +- [ArmCcaBootSync/Readme.md](https://gitlab.arm.com/linux-arm/edk2-cca/-/blob/cca/4441_measured_boot_v1/ArmVirtPkg/ArmCcaBootSync/Readme.md) +- Appendix A (Boot Injection) in [the RHI specifications document](https://confluence.arm.com/display/FENIMORE/RHI+specification) + + +In the next section, you will launch realms and see how Arm CCA BootSync can be used. diff --git a/content/learning-paths/servers-and-cloud-computing/cca-bootsync/flow.md b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/flow.md new file mode 100644 index 0000000000..23306e8206 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/cca-bootsync/flow.md @@ -0,0 +1,465 @@ +--- +# User change +title: "Arm CCA Boot Sync" + +weight: 3 # 1 is first, 2 is second, etc. + +# Do not modify these elements +layout: "learningpathall" +--- +## Overview + +In this section you will run the **User Context** service in a docker container, +launch a **CCA realm** on **Arm FVP** running in a separate docker container +and see how Arm CCA BootSync can be used to define realm EFI variables and share secret data with realms. +You will also see how the defined EFI variables can be used to enable UEFI Secure Boot and +the shared secret data can be used for providing access to encrypted file systems. + +## Install dependencies + +Start by installing Docker. On Ubuntu 24.04 LTS, set up Docker’s APT repository: + +```bash +# Add Docker's official GPG key: +sudo apt-get update +sudo apt-get install -y ca-certificates curl +sudo install -m 0755 -d /etc/apt/keyrings +sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc +sudo chmod a+r /etc/apt/keyrings/docker.asc + +# Add the repository to APT sources: +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt-get update +``` + +Install Git and Docker packages: +``` +sudo apt-get install -y git docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +``` + +Add your user name to the Docker group (open a new shell after this so the change takes effect): +``` bash +sudo usermod -aG docker $USER +newgrp docker +``` + +## Start User Context service + +First, pull the docker container image with the pre-built User Context service, and then run the container. +Running the container with specified name and network, would allow later to connect to the services running in the +container using the container name as a host name. + +```bash +docker pull armswdev/cca-learning-path:cca-key-broker-v4 +docker network create cca-trustee +docker run --rm -it --network cca-trustee --name user-context armswdev/cca-learning-path:cca-key-broker-v4 +``` + +Now within your running docker container, start User Context service using `run-user-context-service.sh` script. +The User Context service in this Learning Path is part of the [EDK2](https://gitlab.arm.com/linux-arm/edk2-cca/-/tree/cca/4441_measured_boot_v1/ArmVirtPkg/ArmCcaBootSync/UserContext) project. +It has been created specifically for POC purposes, so is intentionally small and simple to understand, and is not designed for production use. + +When started first time the script would generate SecureBoot signing certificates and create a Provisioning Data file. +The Provisioning Data is a binary file generated by [GenPd.py](https://gitlab.arm.com/linux-arm/edk2-cca/-/blob/cca/4441_measured_boot_v1/ArmVirtPkg/ArmCcaBootSync/Scripts/GenPd.py) script. +The file contains EFI variables defintions required for enabling SecureBoot. + +You will be asked for a passphrase which will be used for Secure boot signing certificates. + +```bash +./run-user-context-service.sh +``` + +## Launch a CCA Realm without SecureBoot enabled. + +With the User Context service running in one terminal, open up a new terminal in which you will run CCA realms. + +Pull the Docker image with the pre-built FVP, and then run the container connected to the same Docker network: + +```bash +docker pull armswdev/cca-learning-path:cca-simulation-v4 +docker run --rm -it --network cca-trustee armswdev/cca-learning-path:cca-simulation-v4 +``` + +Within your running container, launch the `run-cca-fvp.sh` script to run the Arm CCA pre-built binaries on the FVP: + +```bash +./run-cca-fvp.sh +``` + +The `run-cca-fvp.sh` script uses the `screen` command to connect to the different UARTs in the FVP. + +When the host Linux boots, log in: + +Enter root as the username: +```output + +Welcome to the CCA host +host login: root +(host) # +``` + +Change directory to `/cca` and use `lkvm-bootsync` to launch a guest Linux in a Realm. +In the command line paramaters we specify "user-context" as the User Context service host name, +its default port and Realm Personalisation value (RPV). +RPV is a user-provided byte string (up to 64 bytes) that allows you to distinguish between Realms. + +```bash +cd /cca +./lkvm-bootsync run --realm --disable-sve --irqchip=gicv3-its \ + --firmware KVMTOOL_EFI_SECUREBOOT.fd \ + -c 1 -m 512 --no-pvtime --pmu \ + --disk guest-disk.img --virtio-transport pci \ + --service-ip user-context \ + --service-port 1080 \ + --realm-pv ARMCCA01 +``` + +You should see the realm boot. + +In the realm boot output you can see that UEFI Secure Boot is not mentioned in EFI messages: +```output +Shell> bootaa64.efi root=/dev/vda2 acpi=force ip=on +EFI stub: Booting Linux Kernel... +EFI stub: Generating empty DTB +EFI stub: Exiting boot services... +``` + +After the realm boots, log in, using the root again as the username: + +```output +Welcome to the CCA realm +realm login: root +(realm) # +``` + +Using `efivar` utility you can check EFI variables to confirm that Secure Boot is not enabled: + +```bash { output_lines = "3" } +mount -t efivarfs efivarfs /sys/firmware/efi/efivars +efivar -p -d -n {global}-SecureBoot +0 +``` + +Stop the realm: + +```bash +poweroff +``` + +On the terminal with the User Context service you can see that during boot the realm firmware +requested a Variable Data file which is missing. As a result the BootSync procedure failed. + +``` output +INFO: BIB Variable Data Requested +FileName = ARMCCA01_VAR.dat +Error: ARMCCA01_VAR.dat Not found! +Error: Boot Sync failed. +Info: Session State: ConnectionEstablished +Info: Attestation State: AttSuccess +Info: BootSync State: BootSyncNotDone +``` + +In the next step we will fix the BootSync procedure. + +## Launch a CCA Realm with SecureBoot enabled. + +On the terminal with the User Context service stop the service by pressing `Ctrl-C`. + +Copy the generated Provisioning Data file to a realm Variable data file with a name `_VAR.dat`: +``` bash +cp SecureBoot/SecBootCert/pd.bin SecureBoot/ARMCCA01_VAR.dat +``` + +Create a Secret Data file with some secret data which will be shared with a realm with the same RPV: +``` bash +echo "My Realm secret data" > SecureBoot/ARMCCA01_SEC.dat +``` + +Start User Context service: +```bash +./run-user-context-service.sh +``` + +On the terminal with FVP, relaunch the realm: +```bash +cd /cca +./lkvm-bootsync run --realm --disable-sve --irqchip=gicv3-its \ + --firmware KVMTOOL_EFI_SECUREBOOT.fd \ + -c 1 -m 512 --no-pvtime --pmu \ + --disk guest-disk.img --virtio-transport pci \ + --service-ip user-context \ + --service-port 1080 \ + --realm-pv ARMCCA01 +``` + +On the terminal with the User Context service you can see that the attestation was successfull and +BootSync completed: +``` outout +Info: Received FIN. Disconnecting. +Info: Session State: UnConnected +Info: Attestation State: AttSuccess +Info: BootSync State: BootSyncCompete +``` + +But, the realm would fail to boot Linux kernel: +``` output +Shell> bootaa64.efi root=/dev/vda2 acpi=force ip=on +Script Error Status: Access Denied (line number 1) +``` + +Stop the realm by entering "reset" command to EFI shell prompt: +``` bash +reset +``` + +Linux kernel successfully booted in the realm without SecureBoot enabled, +but failed to boot after you enabled SecureBoot. This happened because we are using a realm file system image +with an unsigned kernel. You will fix it in the next step. + +## Launch a CCA Realm with SecureBoot enabled and a signed Linux kernel + +On the terminal with FVP use `sign_guest_kernel.sh` script to sign realm Linux kernel. +You will be asked for the passphrase you used for Secure boot signing certificates. + +```bash { output_lines = "2-3" } +sign_guest_kernel.sh +Signing kernel image: +Enter PEM pass phrase: +Signing Unsigned original image +``` + +Relaunch the realm: +```bash +cd /cca +./lkvm-bootsync run --realm --disable-sve --irqchip=gicv3-its \ + --firmware KVMTOOL_EFI_SECUREBOOT.fd \ + -c 1 -m 512 --no-pvtime --pmu \ + --disk guest-disk.img --virtio-transport pci \ + --service-ip user-context \ + --service-port 1080 \ + --realm-pv ARMCCA01 +``` + +You should see the realm boot. + +In the realm boot output you can see in EFI messages that UEFI Secure Boot is enabled: +```output +Shell> bootaa64.efi root=/dev/vda2 acpi=force ip=on +EFI stub: Booting Linux Kernel... +EFI stub: UEFI Secure Boot is enabled. +EFI stub: Generating empty DTB +EFI stub: Exiting boot services... +``` + +After the realm boots, log in, using the root again as the username: + +```output +Welcome to the CCA realm +realm login: root +(realm) # +``` + +Using `efivar` utility you can check EFI variables to confirm that Secure Boot is enabled: + +```bash { output_lines = "3" } +mount -t efivarfs efivarfs /sys/firmware/efi/efivars +efivar -p -d -n {global}-SecureBoot +1 +``` + +You can also see that EFI SetupMode is disabled: +```bash { output_lines = "2" } +efivar -d -p -n {global}-SetupMode +0 +``` + +Via [securityfs](https://www.kernel.org/doc/Documentation/ABI/testing/securityfs-secrets-coco) you can +access the secret data which is shared with the realm using GRUB_EFI_DISKPASSWD_GUID: + +```bash { output_lines = "3" } +mount -t securityfs none /sys/kernel/security +cat /sys/kernel/security/secrets/coco/736869e5-84f0-4973-92ec-06879ce3da0b +My Realm secret data +``` + +Stop the realm: + +```bash +poweroff +``` + +You have successfully started a realm with UEFI Secure Boot configured and enabled via Arm CCA BootSync. + +## Launch a CCA Realm with an encrypted root file system. + + The secure data shared with realm via Arm CCA BootSync can also be used to provide access to encrypted file systems. + +{{% notice Access to encrypted partitions %}} + +There are different ways you can use to provide realm with access to encrypted partitions using Arm CCA Bootsync. For example: + +- Use an updated version of [Grub](https://gitlab.arm.com/linux-arm/grub-cca/-/tree/cca/4441_measured_boot_v1) as a boot loader. +This version of Grub uses the secret data to open an encrypted partition and load kernel and initrd images from it. +This is an example grub config file: +```output +echo 'Mounting encrypted disk...' +cryptomount -s efisecret (hd0,gpt2) + +echo 'Loading Kernel...' +linux (crypto0)/bootaa64.efi + +echo 'Loading InitRD...' +initrd (crypto0)/initrd.gz + +echo 'Booting Linux...' +boot +``` +Please notice that with the current Grub implementation of Arm CCA BootSync support booted OS will have access to the +Init ramdisk only. + +- Use an init script in an initrd image to unlock and mount the encrypted partition. You will use this approach in the next stages. + +{{% /notice %}} + + +On the terminal with running FVP use `encrypt_rootfs.sh` script to encrypt the root partition in the realm disk image and +add an initrd image into the kernel parameters. +You will be asked for an passphrase which will be used for the encryption. +You can use maximum of 512 characters of upper/lowercase, numbers and symbols. +You can ignore the WARNING message because we're using small size paritions for this demo. + +```bash { output_lines = "2-11" } +encrypt_rootfs.sh +Resizing root file system to accomodate minimal LUKS2 header +resize2fs 1.47.3 (8-Jul-2025) +Resizing the filesystem on /dev/loop0p2 to 260096 (1k) blocks. +The filesystem on /dev/loop0p2 is now 260096 (1k) blocks long. + +tune2fs 1.47.3 (8-Jul-2025) +Encrypting root partition +Enter passphrase for LUKS2-temp-4684d923-d8b7-4371-8bb2-f8667bfb0498.new: +WARNING: keyslots area (1015808 bytes) is very small, available LUKS2 keyslot count is very limited. +Enable Initrd image +``` + +Relaunch the realm: +```bash +cd /cca +./lkvm-bootsync run --realm --disable-sve --irqchip=gicv3-its \ + --firmware KVMTOOL_EFI_SECUREBOOT.fd \ + -c 1 -m 512 --no-pvtime --pmu \ + --disk guest-disk.img --virtio-transport pci \ + --service-ip user-context \ + --service-port 1080 \ + --realm-pv ARMCCA01 +``` + +In the realm boot log you can see that the Init script failed to unlock the encrypted partition: + +```output +[ 32.761651] Run /init as init process +Detecting LUKS containers in vda1-2 +/dev/vda1 is not LUKS +/dev/vda2 is LUKS, attempting unlock. +No key available with this passphrase. +Failed to unlock LUKS partition. Has BootSync been completed? +FAIL finding root on LUKS, loading BusyBox... +can't run '/etc/init.d/rcS': No such file or directory + +Please press Enter to activate this console. +``` + +Press Enter to get into the realm shell. +In the shell you can check that only Init ramdisk is mounted and you can't mount `/dev/vda2`: + +```bash { output_lines = "2-3" } +df -h +Filesystem Size Used Available Use% Mounted on +devtmpfs 174.4M 0 174.4M 0% /dev +``` + +```bash { output_lines = "2" } +mount -t auto /dev/vda2 /cryptroot +mount: mounting /dev/vda2 on /cryptroot failed: Invalid argument +``` + +Stop the realm: + +```bash +poweroff +``` + +The Init script failed to unlock the encrypted partition because we have not shared the encryption passphrase with the realm. +Let's fix that. + +On the terminal with the User Context service stop the service by pressing `Ctrl-C`. + +Save the encryption passpharse into the Secret Data file. Please use `-n` parameter to exclude the trailing newline character. +``` bash +echo -n "" > SecureBoot/ARMCCA01_SEC.dat +``` + +Start User Context service: +```bash +./run-user-context-service.sh +``` + +On the terminal with FVP, relaunch the realm: +```bash +cd /cca +./lkvm-bootsync run --realm --disable-sve --irqchip=gicv3-its \ + --firmware KVMTOOL_EFI_SECUREBOOT.fd \ + -c 1 -m 512 --no-pvtime --pmu \ + --disk guest-disk.img --virtio-transport pci \ + --service-ip user-context \ + --service-port 1080 \ + --realm-pv ARMCCA01 +``` + +In the realm boot log you can see that the Init script successfully unlocked and mounted the encrypted partition: +```output +[ 233.501627] Run /init as init process +Detecting LUKS containers in vda1-2 +/dev/vda1 is not LUKS +/dev/vda2 is LUKS, attempting unlock. +*** LUKS partition unlocked, switching root *** +``` + +After the realm boots, log in, using the root again as the username: + +```output +Welcome to the CCA realm +realm login: root +(realm) # +``` + +You can check that the unlocked encrypted partition `/dev/mapper/cryptroot` mounted as root. + +```bash { output_lines = "2-9" } +df -h +Filesystem Size Used Available Use% Mounted on +devtmpfs 174.4M 0 174.4M 0% /dev +/dev/mapper/cryptroot + 227.9M 93.0M 118.2M 44% / +tmpfs 194.8M 0 194.8M 0% /dev/shm +tmpfs 194.8M 40.0K 194.8M 0% /tmp +tmpfs 194.8M 32.0K 194.8M 0% /run +cgroup 194.8M 0 194.8M 0% /sys/fs/cgroup +``` + +Stop the realm: + +```bash +poweroff +``` + +Stop the FVP: + +```bash +poweroff +``` + +You have successfully tested launching realms with Arm CCA BootSync.