Realm Management Extension (RME)

Introduction to Confidential Compute architecture

In computing, data exists in three states: in transit, at rest, and in use. Data traversing the network is “in transit,” data in storage is “at rest,” and data being processed is “in use.” Today, data is often encrypted ‘at-rest’ in storage and ‘in-transit’ across network, but not while ‘in-use’ in memory and process engine. Before the data can be processed by an application, it must be unencrypted in memory. This leaves the data vulnerable during processing when attackers may target data in memory or during processing by processing engine. Confidential Computing is a technology to protect the ‘data-in-process’ by processing the data in a hardware based protected CPU enclave or trusted execution environments (TEEs). The TEE is secured with encryption keys that prevent malicious foreign execution from attacking and breaching confidential data use.

Arm Confidential Compute architecture (CCA) allows to deploy isolated hardware trusted execution environment called as Realms. Realms allow lower-privileged software, such as an application or a Virtual Machine to protect its content and execution from attacks by higher-privileged software, such as an OS or a hypervisor. The hypervisor however, manages system resources.

The diagram below gives the security model for Arm CCA. For more details refer to the Arm CCA security model.

../../../_images/arm-cca-architecture.png

RME architecture

Realm Management Extension or RME is an extension to Arm v9 arcitecture that defines the set of hardware features and properties that are required to comply with the Arm CCA architecture. As shown in above diagram the RME extends the Arm security model to four states now:

  1. Secure state

  2. Non-secure state

  3. Realm state

  4. Root state

SCR_EL3.{NSE,NS} controls PE security state.

SCR_EL3.{NSE,NS}

Security state

0b00

Secure

0b01

Non-secure

0b10

NA

0b11

Realm

There is no encoding for root state. While in Exception level 3, the current security state is always root, regardless of the value of SCR_EL3.{NSE,NS}.

RME provides hardware-based isolation. In that:
  • Execution in the Realm security state cannot be observed or modified by an agent associated with either the Non-secure or the Secure security state.

  • Execution in the Secure security state cannot be observed or modified by an agent associated with either the Non-secure or the Realm security state.

  • Execution in the Root security state cannot be observed or modified by an agent associated with any other security state.

  • Memory assigned to the Realm security state cannot be read or modified by an agent associated with either the Non-secure or the Secure security state.

  • Memory assigned to the Secure security state cannot be read or modified by an agent associated with either the Non-secure or the Realm security state.

  • Memory assigned to the Root security state cannot be read or modified by an agent associated with any other security state.

Below is an example system architecture for a RME enabled platform.

../../../_images/rme-system-architecture.png
As seen above the RME enabled platform may include following system components:
  1. Requester side filters (GPC - placed after MMUs)

  2. Completer side filters (embedded in interconnects/devices)

  3. Memory Protection Engine (MPE – placed before memory controller)

RME software architecture

Below diagram show the participating software components in an RME software architecture.

../../../_images/rme-software-architecture.png

The platforms implementing these software components may follow a boot flow as mentioned in the Boot flow.

The software components that add support for Arm RME architecture are -

  1. Trusted firmware for M class (TF-M)

  2. Trusted firmware for A class (TF-A)

  3. Realm Management Monitor (TF-RMM)

  4. Linux kernel

  5. Linux KVM tool (lkvm)

  6. KVM unit tests

Platforms implementing RME architecture must also includes a CCA HES (hardware enforced security) module that serves as the root of trust in the CCA chain of trust. Runtime security subsystem (RSS) provides this support.

Validating RME support on RD-Fremont

In order to validate RME architecture support on RD-Fremont platform following test cases should succeed.

  1. Parallelly booting virtual machine in the Realm and the non-secure security state,

  2. Running Realm kvm-unit-tests that test a number of Linux KVM unit tests fo Realm security state.

Follow the Virtualization guide for more details on virtualization support on Neoverse reference design platform.

Build the RD-Fremont platform software stack for buildroot root filesystem by following the Buildroot guide.

Now boot the RD-Fremont fastmodel with the software stack as given in the Buildroot guide with additional model parameters to enable support for Scalable Vector Extensions (SVE). The SVE plugin is available as part of the model package and should be visible in the plugins/ directory in the installed model path. Example to launch the RD-Fremont model to buildroot prompt with SVE:

./boot-buildroot.sh -p rdfremont -a  "--plugin /absolute/path/to/ScalableVectorExtension.so -C SVE.ScalableVectorExtension.veclen=16 -C SVE.ScalableVectorExtension.enable_at_reset=0" -n [true|false]

After boot mount the disk-image that contains Linux kernel for guest, lkvm tool and kvm-unit-tests built with RME support.

a) Running a virtual machine in Realm security state

  • After booting the platform the disk-image partition can be mounted as:

    # mount /dev/vda2 /mnt
    
  • This partition should contain the following files and directories:

    # cd /mnt
    # ls
    Image                kvmtool                ramdisk-buildroot.img
    kvm-ut               lost+found
    
  • Now launch a virtual machine (VM) in Realm security state using lkvm with Linux and buildroot ramdisk images:

    # screen -md -S "<screen_name>" /mnt/kvmtool/lkvm run --realm -c 2 -m 512 -k /mnt/Image -i /mnt/ramdisk-buildroot.img --irqchip gicv3 --console serial -p earlycon
    
  • Considering the <screen_name> in above command is “realm” verify that the screen session is running:

    # screen -ls
    There are screens on:
       198.realm       (Detached)
    
  • Jump to the screen session to see the virtual machine boot in Realm security state:

    # screen -r realm    // <screen_name: realm>
    
  • Example Linux kernel logs from the Realm VM boot:

    Info: # lkvm run -k /mnt/Image -m 512 -c 2 --name guest-200
    [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd840]
    [    0.000000] Linux version 6.7.0-rc4-g3831d84fa0f8 (vivgau01@a077843) (aarch64-none-linux-gnu-gcc (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.1 20231009, GNU ld (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 2.41.0.20231009) #2 SMP PREEMPT Tue Jan 16 04:39:53 UTC 2024
    [    0.000000] KASLR enabled
    [    0.000000] Machine model: linux,dummy-virt
    [    0.000000] RME: Using RSI version 1.0
    [    0.000000] efi: UEFI not found.
    
  • Confirm that the Linux kernel boots in Realm world with the following log:

    [    0.000000] RME: Using RSI version 1.0
    
  • Switch back the console to host using screen command shortcut ‘Ctrl-a d’. Now launch a virtual machine in non-secure security state as well:

    # screen -md -S nsvm /mnt/kvmtool/lkvm run -c 2 -m 512 -k /mnt/Image -i /mnt/ramdisk-buildroot.img --irqchip gicv3 --console serial -p earlycon
    
  • Verify that the Linux kernel boot starts in Non-secure VM.

  • Also check that both screen sessions are running fine:

    # screen -ls
    There are screens on:
       198.realm       (Detached)
       214.nsvm        (Detached)
    
  • Power-off the guests by jumping to the respective screen and executing the command:

    poweroff
    
  • The Realm and Non-secure guests would shutdown gracefully and the following message would be displayed on the console.

    # KVM session ended normally.
    

This completes the launch of virtual machine in Realm security state.

b) Running Realm kvm-unit-tests

Separate set of kvm-unit-test are developed to test various RME architectural features. Some of these include tests for Realm-RSI (Realm Service Interface), PSCI support in realm security state, GIC to validate interrupt support in the Realm, and Realm attestation to check support for remote attestation for realm payloads. As mentioned above build and boot the RD-Fremont platform with build- root filesystem.

  • After booting the platform the disk-image partition can be mounted as:

    # mount /dev/vda2 /mnt
    
  • This partition should contain the following files and directories:

    # cd /mnt
    # ls
    Image                kvmtool                ramdisk-buildroot.img
    kvm-ut               lost+found
    
  • Now run the realm kvm-unit-tests from kvm-ut/ directory.

    # cd kvm-ut/arm/
    # export LKVM=/mnt/kvmtool/lkvm
    # ./run-realm-tests
    
  • This will launch a number of KVM unit tests that are run in Realm security state. An example output looks like below:

    # lkvm run -k ./selftest.flat -m 16 -c 2 --name guest-200
    PASS: selftest: setup: smp: number of CPUs matches expectation
    INFO: selftest: setup: smp: found 2 CPUs
    PASS: selftest: setup: mem: memory size matches expectation
    INFO: selftest: setup: mem: found 16 MB
    SUMMARY: 2 tests
    
    # KVM session ended normally.
    # lkvm run -k ./selftest.flat -m 16 -c 1 --name guest-222
    PASS: selftest: vectors-kernel: und
    PASS: selftest: vectors-kernel: svc
    SKIP: selftest: vectors-kernel: pabt test not supported in a realm
    SUMMARY: 3 tests, 1 skipped
    
    # KVM session ended normally.
    # lkvm run -k ./selftest.flat -m 16 -c 1 --name guest-244
    PASS: selftest: vectors-user: und
    PASS: selftest: vectors-user: svc
    SUMMARY: 2 tests
    
    # KVM session ended normally.
    # lkvm run -k ./selftest.flat -m 32 -c 4 --name guest-266
    INFO: selftest: smp: PSCI version: 1.1
    INFO: selftest: smp: PSCI method: smc
    INFO: selftest: smp: CPU  1: MPIDR=0080000001
    INFO: selftest: smp: CPU  2: MPIDR=0080000002
    INFO: selftest: smp: CPU  0: MPIDR=0080000000
    INFO: selftest: smp: CPU  3: MPIDR=0080000003
    PASS: selftest: smp: MPIDR test on all CPUs
    INFO: selftest: smp: 4 CPUs reported back
    SUMMARY: 1 tests
    

This completes the Realm kvm-unit-tests run.


Copyright (c) 2023, Arm Limited. All rights reserved.