Skip to content

Instantly share code, notes, and snippets.

@chadmed
Created January 14, 2023 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chadmed/ea318ebb9574354cb44be5c31698dfc9 to your computer and use it in GitHub Desktop.
Save chadmed/ea318ebb9574354cb44be5c31698dfc9 to your computer and use it in GitHub Desktop.

Apple Platform Security Crash Course

Introduction

The Apple Silicon platform has been designed from the ground up to offer properly configured systems an extremely secure operating environment that is resilient to multiple forms of attack. The security model is based on the Swiss Cheese Model - no single security mechanism can guarantee an acceptable level of security on its own, so mechanisms are layered to cover each others' holes. For most of this article, we will be investigating a standard macOS environment in Full Security mode. Explanations on how these features interact with nonstandard environments will of course focus on Linux as configured by the Asahi tooling, however can be generalised.

Platform security features are orchestrated by the Secure Enclave Processor (SEP). An overview of the SEP's features, the different boot policies, and the boot picker itself is available at [[Introduction to Apple Silicon]]. This page instead attempts to extrapolate upon and clarify the concepts which may be of interest to users and system maintainers.

The Apple Silicon security model is built upon four core layers:

  • A hardware-backed trust root and credential store
  • Guaranteed integrity of system data
  • Transparent encryption of data at rest
  • Authenticated encryption of user data

Boot policy and the chain of trust

  1. Every piece of critical firmware is at minimum signed by Apple, including all stages of iBoot. The system will refuse to boot if any of this has been tampered with.

  2. The macOS kernelcache of the boot disk is signed by Apple and verified by the system. If the kernelcache is not signed by Apple or its hash does not match what the machine expects, it will not boot.

  3. The OS filesystem is a sealed, hashed snapshot. Every file inside it is also hashed. If the hash of the image or any file inside of it does not match what is expected, the system will not boot. Mutable user data is stored on an entirely different volume. After the snapshot (A) is verified, it is unioned with the user data volume (B) to present the complete root (C) such that $C = (A \cup B)$. Files cannot intersect the two volumes, and it is impossible to mutate the snapshot in Full Security mode.

  4. The kernelcache is paired to one - and only one - OS snapshot. You cannot drop in a kernelcache from Filesystem A and boot Filesystem B with it, nor can you set Filesystem A as the boot disk then pivot to Filesystem B as the root. The system will stop booting if the kernelcache is not paired to the root filesystem being mounted or if the booted APFS container is not the one the kernelcache came from.

  5. The SEP can keep track of multiple security contexts. These security settings are stored in per-container boot policies so that one compromised container cannot be used to capture another.

  6. The SEP is aware of "Machine Owner" credentials, which are paired to the credentials of the first user account created on the machine. This is persistent even across macOS installs. To alter any platform security settings or boot policies, the SEP must be satisfied that the Machine Owner is both physically present and authenticated. The SEP will refuse to alter any security or boot policies if these criteria are not met.

  7. As of macOS 12, the recoveryOS image is paired to the blessed boot container (the default boot container). The SEP will not allow you to alter the boot policy of a different container. You must first bless that container, which requires authentication.

  8. You cannot boot from unverified removable media without first having the SEP bless it. This requires being logged in to 1TR or a trusted OS the SEP already knows about.

This setup guarantees a hardware chain of trust not just from the SEP, but from the Machine Owner. Remote or silent tampering of the boot chain is effectively impossible, as the platform will not allow any changes to be made to this arrangement without the Machine Owner being physically present.

Being able to track security policies on an APFS container level is a beautiful piece of design and unique to this platform. This has been done specifically to enable the loading and execution of untrusted code without compromising on the security and integrity guarantees Apple make of macOS. Apple have in fact spent time and effort fixing problems in their security config tools that only affect the loading of non-macOS binaries.

For Linux, we leverage this by creating a small APFS container and setting the security on that to Permissive, which lets us use Apple's tooling to create a valid "macOS kernel" out of m1n1, our bootloader. The tooling signs the resultant binary, and tells the SEP that it is allowed to boot it as the kernelcache for our APFS container. We do not - and never will - alter the security settings of any real macOS container, nor will Apple's "restrictive" security policies on such containers ever hinder the installation of a third party OS on these machines.

Disk encryption, FileVault and LUKS

Since the introduction of the T2, Macs have had quite robust and transparent per-volume encryption. It is for this reason that Apple cannot replace faulty SSDs in post-T2 Macs without total data loss. The default state for this system is data encrypted at rest - the machine will transparently decrypt the data in flight with its own keys, while it remains encrypted on the disk. There is almost no performance penalty for this. On Apple Silicon machines, the SEP generates a Volume Encryption Key and xART for every APFS volume. Data on the volume is encrypted/decrypted in flight. Keys are stored by the SEP in airgapped memory. No other part of the system has any access to the keystore, and sepOS does not expose keys to the rest of the system. It is important to be aware that once the machine has powered on and the SEP is satisfied with the state of iBoot and the system firmware, the keys are unwrapped and all data is accessible in the clear across all volumes. This is where FileVault comes in for macOS.

When FileVault is enabled for an APFS volume, the VEK and xART are wrapped with a Key Encryption Key, which is backed by user credentials from the macOS instance in question. The machine will be unable to read the user data volume of the FileVault protected container until these credentials are provided at startup. Enabling this is instantaneous on Apple Silicon machines, as the disk is already encrypted and the only required operation is generating the KEK and recovery key. The system snapshot, Preboot, and recovery volumes are not protected by FileVault. These partitions are immutable, backed by the SEP, and contain no user data and therefore do not particularly benefit from FileVault in any case.

We can very closely emulate this with LUKS on top of LVM and achieve effective FDE. We have the luxury of disregarding the APFS stub since the only thing we care about there are m1n1 and Recovery, both of which are verified by iBoot. An existing weakness is that /boot must be stored in the clear, and there is currently no Secure Boot or Measured Boot analogue with which we can guarantee the integrity of the kernel or initramfs. Users may choose to point their bootloader to removeable media once this is better supported to mitigate this. Beyond that, any bootloader which supports LUKS and LVM will work with a standard cryptsetup workflow. once the non-APFS space on the machine's disk has been partitioned to the user's liking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment