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

Architecture Overview

This document describes how the system extends Android to support confidential computing by allowing selected app code to run inside a protected execution environment.

The architecture enables an Android service to execute inside a Realm VM while still being exposed to client applications through the standard Binder IPC mechanism. From the perspective of the client, the service behaves like a regular Android bound service, while its implementation runs in an isolated environment.

Architecture Diagram

Execution Domains

Normal World (Host Android)

Runs full Android, hosts the entry point for confidential services, manages the Realm VM lifecycle, and bridges communication with services running in the Realm.

Realm World (Confidential World running Realm VMs)

Provides a hardware-assisted isolated environment for sensitive code and data. It runs a minimal Android-based runtime on Microdroid, initializing only the components needed for service execution, including a lightweight Dalvik VM for Java-based services.

Components

Confidential Computing Components

These components are implemented as part of this system and provide the integration between Android and the confidential execution environment.

  • CC Proxy: CC Proxy is an Android bound service that runs in the Normal World and serves as the entry point for all client interactions. It exposes the service interface using AIDL, allowing client applications to bind and invoke methods using standard Android IPC. Internally, CC Proxy is responsible for forwarding these requests to the Realm VM. In addition to request forwarding, CC Proxy manages the lifecycle of the Realm VM. It uses an internal helper (VmManager) to coordinate VM creation, startup, and connection to the Realm-side service. By handling both IPC bridging and lifecycle management, CC Proxy allows the confidential service to appear indistinguishable from a regular Android service.

  • CC Stub: CC Stub runs in the Realm World and acts as the server-side counterpart to CC Proxy. It receives incoming Binder RPC calls over vsock from the Normal World, and dispatches them to the appropriate service implementation. It also handles service initialization and binding within the Realm environment. This separation ensures that communication logic remains isolated from the actual business logic, allowing service implementations to remain simple and unchanged.

  • CC Service: CC Service is the confidential code implemented by app developers and runs inside the Realm VM. It follows the standard Android bound service model, with an AIDL-defined interface and a Java-based implementation. Because the execution model closely matches that of a regular Android service, existing code can often be reused with minimal or no modification. The main difference is that the service executes in a protected environment and is accessed remotely via Binder RPC.

  • Provisioning Client: The Provisioning Client runs inside the Realm World and is responsible for provisioning confidential data from external Provisioning Servers. It is controlled by the Microdroid Manager, which executes it once a CC Service requests the provisioning operation. During the provisioning operation, the Provisioning Client establishes a secure channel with an external Provisioning Server using the RA-TLS protocol (a protocol that combines Remote Attestation with TLS). Once the secure channel is established, the Provisioning Client downloads confidential data into the location inside the encrypted storage mount point requested by the CC Service.

  • encryptedstore: The encryptedstore is an AVF Encrypted Store mechanism that provides CC Services with persistence and confidentiality of data at rest. The encrypted storage uses a virtual block device on the guest, which is backed by a disk image file stored on the host. In our solution, the encryption keys used by encryptedstore are derived from the Realm Sealing Key (which is rooted in a Hardware Unique Key and is bound to the Realm authority and identity data) and are also bound to the Microdroid and CC Service application authority data. This ensures that only a particular CC Service that saved the data in encryptedstore on a particular hardware platform can access it.

Platform Components

The system relies on several existing platform components that provide virtualization and isolation capabilities.

  • Android Virtualization Service: The Virtualization Service is part of Android and provides APIs for managing virtual machines. In this architecture, it is used by CC Proxy to create and control the Realm VM. It handles tasks such as VM initialization, resource allocation, and lifecycle management. By relying on this existing service, the system avoids introducing a custom VM management layer and remains aligned with Android’s virtualization framework.

  • KVM/lkvm: KVM provides the underlying virtualization support at EL2. It is responsible for running the Realm VM and ensuring that it is properly isolated from the host system. With CCA-related extensions, KVM enables the creation of protected execution environments backed by hardware.

  • Realm Management Monitor (RMM): lset-RMM is part of the confidential computing platform that supports the Arm CCA and is responsible for managing Realm execution. It handles operations such as Realm creation, execution, and termination, and works with the hypervisor to enforce isolation guarantees between the Normal World and the Realm World.

  • Microdroid: Microdroid is Android’s minimal guest image for protected VMs under the Android Virtualization Framework. A mini-Android OS for protected VMs (pVMs) that loads a main binary and shared libraries from an APK, activates APEX modules on the guest, builds native code against Bionic, and uses Binder RPC over vsock for IPC—rather than shipping full-device Android.

AIDL Engine Behind the Scene

The AIDL Engine has been extended with a new feature that automates the integration between the Normal World and the Realm World.

When an AIDL interface is annotated with @GenerateCCService, the engine generates the necessary glue code, including the CC Proxy and CC Stub components. This removes the need for developers to manually implement cross-domain communication logic.

As a result, developers can focus on defining service interfaces and implementing business logic, while the system handles the underlying infrastructure.

Inter-world Communication

Communication between the Normal World and the Realm World is implemented using a layered Binder stack: Binder IPC between client applications and CC Proxy, and Binder RPC to extend Binder semantics across process and VM boundaries. This design allows the system to preserve the familiar Binder programming model while enabling communication across isolated environments.

Service interaction diagrams (high level)

A typical request flows through the system as follows:

CC Service startup

sequenceDiagram
    autonumber
    box Normal World (Android)
      participant C as Client App
      participant P as CCProxyService
      participant V as VmManager
      participant VM as VirtualMachine
      participant VS as VirtualizationService (Host)
      participant VMM as VirtualMachineManager
      participant VMGR as virtmgr
    end
    box Realm (Guest Realm VM hosting Microdroid)
      participant MM as MicrodroidManager (Guest)
      participant CCS as CCStub
      participant CCSE as CCService (User Java)
    end

    %% ---------- Boot & Connect Phase ----------
    Note over P, V: CCPlugIn
    Note over VM, VMM: framework-virtualization library
    Note over CCS, CCSE: Microdroid launcher/payload
    C->>C: context.bindService()
    C-->>P: onCreate() (via Activity Manager)
    note over V: Initialize VirtualMachineConfig
    P->>V:setVmServiceCallback()
    P->>V:vmRun()
    V->>VMM:getOrCreate(VirtualMachineConfig, ...)
    VMM->>VM:create(VirtualMachineConfig, ...)
    activate VM
    VM->>VS:getInstance()
    VS->>VS:nativeSpawn()
    VS-)VMGR: spawn process
    activate VMGR
    VMGR-->>VS: clientFd
    VS->>VS:nativeConnect(clientFd)
    VS-->>VM: VirtualMachine instance
    Note over VM: Initialize InstanceId, instance and encryptedstore partitions
    VM-->>VMM: VirtualMachine instance
    deactivate VM
    VMM-->>V: VirtualMachine instance
    V->>VM:run()
    Note over VM: Prepare vm config, setup console for virtmgr
    VM->>VMGR:createVm(config, consolein, consoleout, ...)
    VMGR-->>VM: IVirtualMachine instance
    VM->>VMGR: IVirtualMachine.registerCallback()
    VM->>VMGR: IVirtualMachine.start()
    V->>VM:setCallback()
    VMGR->>VMGR: start lkvm (with Arm CCA Realms enabled)
    VMGR->>MM: lkvm launches Microdroid in Realm VM
    activate MM
    MM->>MM: try_run_payload()
    MM-)CCS: spawn Microdroid Launcher/NativeStub
    activate CCS
    MM-->>VMGR: notifyPayloadStarted()
    VMGR-->>VM: onPayloadStarted()
    VM-->>V: onPayloadStarted()
    CCS-)CCSE: load and initialize CCService (DEX)
    activate CCSE
    note left of CCS: The VSOCK port of the Service is exposed to the host
    CCS-->>CCS: Setup Binder RPC/VSOCK server
    CCSE-->>MM: AVmPayload_notifyPayloadReady()
    MM-->>VMGR: notifyPayloadReady()
    VMGR-->>VM: onPayloadReady()
    VM-->>V: onPayloadReady()
    V->>VM: connectToVsockServer()
    Note over VM, CCS: The CC Proxy Service establishes Binder RPC connection over VSOCK with the CC Stub obtaining IBinder reference to IRealmService Stub
    VM--xCCS: Binder RPC over VSOCK
    VM-->>V: IBinder reference to IRealmService
    V->>P: onVmServiceReady(IRealmService reference)
    P->>CCS: IRealmService.onBindForTargetService()
    CCS->>CCSE: onCreate()
    CCS->>CCSE: onBind()
    CCSE-->>CCS: IBinder reference to CC Service
    CCS-->>P: IBinder reference to CC Service
    note left of P: CCProxyService got the IBinder reference to CC Service,<br>it is now ready to work
    deactivate CCSE
    deactivate CCS
    deactivate MM
    deactivate VMGR

End-to-end call path (example call)

From the client’s perspective, the interaction is identical to calling a regular Android service. The cross-domain communication is handled transparently by the system.

sequenceDiagram
    autonumber
    box Normal World (Android)
      participant C as Client App
      participant P as CCProxyService
    end
    box Realm (Guest Realm VM hosting Microdroid)
      participant CCSE as CCService (User Java)
    end

    %% ---------- End to End call ----------
    C->>C: context.bindService(ServiceConnection instance)
    C-->>P: onCreate() (via Activity Manager)
    Note over P: Here are the steps related to startup of VM and CC Service inside VM<br>(details are on the CC Service startup diagram)
    C->>P: onBind() (via Activity Manager)
    P-->>C: ServiceConnection.onServiceConnected(IExampleInterface proxy)(via Activity Manager)
    C->>C: Add button is clicked
    C->>C: Parse a and b values from text fields
    Note over P: addInt() is implemented by CC Proxy's IExampleInterface.Stub
    C->>P: addInt(a, b)
    activate P
    Note over CCSE: addInt() is implemented by CC Service's IExampleInterface.Stub
    P->>CCSE: addInt(a, b)
    activate CCSE
    CCSE-->>P: result
    deactivate CCSE
    P-->>C: result
    C-->>C: Display result
    deactivate P