| AWS Nitro Enclaves |
| ================== |
| |
| `AWS Nitro Enclaves <https://aws.amazon.com/ec2/nitro/nitro-enclaves/>`_ |
| are isolated compute environments that run alongside EC2 instances. |
| They are created by partitioning CPU and memory resources from a parent |
| instance and launching a signed Enclave Image Format (EIF) file inside |
| a confidential VM managed by the Nitro Hypervisor. |
| |
| QEMU supports launching Nitro Enclaves on EC2 instances that have |
| enclave support enabled, using the ``nitro`` accelerator and the |
| ``nitro`` machine type. |
| |
| Prerequisites |
| ------------- |
| |
| * An EC2 instance with Nitro Enclaves enabled |
| * The ``nitro_enclaves`` kernel module loaded (provides ``/dev/nitro_enclaves``) |
| * CPU cores allocated to the Nitro Enclaves pool via ``nitro-enclaves-allocator`` |
| * Huge pages allocated for Nitro Enclaves via ``nitro-enclaves-allocator`` |
| |
| Quick Start |
| ----------- |
| |
| Launch a Nitro Enclave from a pre-built EIF file:: |
| |
| $ qemu-system-x86_64 -accel nitro,debug-mode=on -M nitro -nographic \ |
| -smp 2 -m 512M -kernel enclave.eif |
| |
| Launch an enclave from individual kernel and initrd files:: |
| |
| $ qemu-system-x86_64 -accel nitro,debug-mode=on -M nitro -nographic \ |
| -smp 2 -m 512M -kernel vmlinuz -initrd initrd.cpio \ |
| -append "console=ttyS0" |
| |
| The same commands work with ``qemu-system-aarch64`` on Graviton based EC2 |
| instances. |
| |
| Accelerator |
| ----------- |
| |
| The ``nitro`` accelerator (``-accel nitro``) drives the |
| ``/dev/nitro_enclaves`` device to create and manage a Nitro Enclave. |
| It handles: |
| |
| * Creating the enclave VM slot |
| * Donating memory regions (must be huge page backed) |
| * Adding vCPUs (must be full physical cores) |
| * Starting the enclave |
| * Notifying vsock bus devices of the enclave CID |
| |
| Accelerator options: |
| |
| ``debug-mode=on|off`` |
| Enable debug mode. When enabled, the Nitro Hypervisor exposes the |
| enclave's serial console output via a vsock port that the machine |
| model automatically connects to. In debug mode, PCR values are zero. |
| Default is ``off``. |
| |
| Machine |
| ------- |
| |
| The ``nitro`` machine (``-M nitro``) is a minimal, architecture-independent |
| machine that provides only what a Nitro Enclave needs: |
| |
| * RAM (huge page backed via memfd) |
| * vCPUs (defaults to ``host`` CPU type) |
| * A Nitro vsock bus with: |
| |
| - A heartbeat device (vsock server on port 9000) |
| - A serial console bridge (vsock client, debug mode only) |
| |
| Communication to the Nitro Enclave is limited to virtio-vsock. The Enclave |
| is allocated a CID at launch at which it is reachable. A specific CID can |
| be requested with ``-accel nitro,enclave-cid=<N>`` (0 lets the hypervisor |
| choose). The assigned CID is readable from the vsock bridge device:: |
| |
| (qemu) qom-get /machine/peripheral/nitro-vsock enclave-cid |
| |
| EIF Image Format |
| ^^^^^^^^^^^^^^^^ |
| |
| Nitro Enclaves boot from EIF (Enclave Image Format) files. When |
| ``-kernel`` points to an EIF file (detected by the ``.eif`` magic |
| bytes), it is loaded directly into guest memory. |
| |
| When ``-kernel`` points to a regular kernel image (e.g. a bzImage or |
| Image), the machine automatically assembles a minimal EIF on the fly |
| from ``-kernel``, ``-initrd``, and ``-append``. This allows standard |
| direct kernel boot without external EIF tooling. |
| |
| CPU Requirements |
| ^^^^^^^^^^^^^^^^ |
| |
| Nitro Enclaves require full physical CPU cores. On hyperthreaded |
| systems, this means ``-smp`` must be a multiple of the threads per |
| core (typically 2). |
| |
| Nitro Enclaves can only consume cores that are donated to the Nitro Enclave |
| CPU pool. You can configure the CPU pool using the ``nitro-enclaves-allocator`` |
| tool or manually by writing to the nitro_enclaves cpu pool parameter. To |
| allocate vCPUs 1, 2 and 3, you can call:: |
| |
| $ echo 1,2,3 | sudo tee /sys/module/nitro_enclaves/parameters/ne_cpus |
| |
| Beware that on x86-64 systems, hyperthread siblings are not consecutive |
| and must be added in pairs to the pool. Consult tools like ``lstopo`` |
| or ``lscpu`` for details about your instance's CPU topology. |
| |
| Memory Requirements |
| ^^^^^^^^^^^^^^^^^^^ |
| |
| Enclave memory must be huge page backed. The machine automatically |
| creates a memfd memory backend with huge pages enabled. To make the |
| huge page allocation work, ensure that huge pages are reserved in |
| the system. To reserve 1 GiB of memory on a 4 KiB PAGE_SIZE system, |
| you can call:: |
| |
| $ echo 512 | sudo tee /proc/sys/vm/nr_hugepages |
| |
| Emulated Nitro Enclaves |
| ----------------------- |
| |
| In addition to the native Nitro Enclaves invocation, you can also use |
| the emulated nitro-enclave machine target (see :doc:`i386/nitro-enclave`) |
| which implements the x86 Nitro Enclave device model. While -M nitro |
| delegates virtual machine device emulation to the Nitro Hypervisor, -M |
| nitro-enclave implements all devices itself, which means it also works |
| on non-EC2 instances. |
| |
| If you require NSM based attestation backed by valid AWS certificates, |
| you must use -M nitro. The -M nitro-enclave model does not provide |
| you with an AWS signed attestation document. |