What do Pointer Authentication Codes mean for iOS jailbreaking?

What do Pointer Authentication Codes mean for iOS jailbreaking?

Yesterday,  Sep 12th,  Apple announced their next generation of iPhones. The iPhone X [s], X [s] Max and X [r] are the new members of the iPhone family and "the most advance iPhones Apple has ever created". You can watch the full presentation here. They talked about their new hardware, new features, new sizes, etc. But one of the most important aspects of these new phones they didn't mention is the adoption of a new version of the ARM architecture: ARMv8.3. With ARMv8.3 Qualcomm (and therefore Apple) brings a new set of instructions that use an amazing memory protection technique called Pointer Authentication Codes. And this is what this means for iOS jailbreaking:

Most of the public jailbreaks to date involve buffer overflows, integer overflows, return-oriented programming (ROP), memory leaks among other memory attacks. The basic idea of these attacks is to be able to execute attacker controlled code and try to do it with as high privileges as possible. All modern architectures use some type combination of memory protections such as canaries, DEP, ASLR, but all of these have been defeated, specifically on iOS/ARMv8-a this has made it possible for jailbreaks on the latest software and hardware like the jailbreak on iOS 11.3.1 to 12 beta 4 even on the iPhone X.

With the introduction of the iPhone X [s] and its new A12 Bionic chip, Apple is upgrading to ARMv8.3 and along with this architecture come the Pointer Authentication Codes (PAC). As Luca Todesco tweeted:

To understand PACs we need to move to the world of cryptography and talk a bit about Message Authentication Codes (aka MACs). MACs are short blobs of data or tags that are used to identify if some piece of data was modified or not. MACs are intended to provide integrity to messages. There are many ways to construct MACs on messages, but informally they all use a secret key, a signing algorithm and a verification algorithm.

Imagine there's a publicly available signing algorithm (S) and a verifying algorithm (V), you and I share a secret key (k), that only we know and I want to send a message (m) to you and you need to verify it came from me. Regardless of m being encrypted or plaintext, we'd perform these operations:

  • I'd calculate a MAC on m: tag := S(m,k)
  • Then I'd send you m and tag
  • Upon reception, you'd calculate the MAC on m: tag_to_verify := S(m,k)
  • And verify if the tags are the same: if V(tag, tag_to_verify) == true { accept_message }

A popular MAC is HMAC or hash-based message authentication code, it uses a hash function (like SHA256) for the signing and verification algorithms and a secret key. HMAC is commonly used to provide integrity to ciphertexts encrypted using Authenticated Encryption modes such as aes-128-cbc-hmac-sha-256. HMAC is just one of may other constructions of secure MACs.

There's a principle in cryptography called "The Kerckhoffs's principle" that states:

A cryptosystem should be secure even if everything about the system, except the key, is public knowledge

This is true in MAC constructions, meaning the signing and verification algorithms are known, the only part that's secret is the key. The important take away is that for secure constructions of MACs if an attacker wants to create a valid MAC on an arbitrary message (for example a modified version of a message), they need to compromise the secret key, otherwise they'll produce an invalid MAC and the system will reject the message.

An example of a MAC in use:

source: wikipedia.org

Back to ARMv8.3 and Pointer Authentication Codes; PACs use exactly the same primitive as MACs but instead of arbitrary messages (blobs of data), they provide integrity to pointers.

tl;dr on how PACs work in ARMv8.3:

  • Since the 64bit architectures' address space is less than 64 bits, Qualcomm can utilze the unused bits for the PACs.
  • Since pointers have different purposes throughout a program, a context variable is added.
  • There are 5 different keys used for the PACs depending on the purpose of a pointer.
  • The instruction encoding determines which key to use.
  • The context value is used for isolating pointers using the same key.
  • There are two main operations needed for Pointer Authentication: computing and adding a PAC, and verifying a PAC and restoring the pointer value.
  • Qualcomm designed their own block cipher called QARMA for their PAC construction.

Qualcomm is basically adding integrity information (the PACs) on the unused bits of an instruction and before jumping to a pointer they check these PACs and if the verification fails an authentication failure error is thrown and the program won't execute the next instruction. You can read Qualcomm's paper on Pointer Authentication Codes to get the full description. You can read Jonathan Levin's post about this as well.

The, somewhat, good news is that cryptographic systems are very hard to get right. SSL/TLS, cryptocoins, full disk encryption, etc. prove that we need to constantly update our crypto-systems to avoid attacks and some of these systems have been around for 20-30 years and have gone through the scrutiny of many experts. This means that these PACs are susceptible to similar attacks we see on MACs and cryptographic systems. Some of these are:

  • Key management Attacks: They way the devices generate PAC keys has to work properly, an attacker should not be able to predict keys.
  • An attacker should not be able to produce a valid PAC after obtaining many valid PACs from the system.
  • Timing attacks: The verification algorithm needs to take the same time for different tags and for equal tags.
  • Side-channel attacks: An attacker shouldn't be able to retreive a key by monitoring, for example, the time it takes to execute an instruction with different types of pointers.

What's interesting to me is that on top of being memory management ninjas, hackers will now have to learn about cryptography and the different attacks they can perform on integrity checks before they can defeat the memory/stack protections that Qualcomm added on ARMv8.3, thus making it very hard for a jailbreak on the iPhone X [s].

I'm sure these hackers will figure it out but to me it's more exciting knowing that a topic that really, really interests me: cryptography, is now combined with other memory protections to harden iPhones.

And hackers already have ideas on how to attack PACs and are excited about a challenge:

If you see any errors on this article please reach out on Twitter and let me know (@ivRodriguezCA) and I'll fix them. Thanks!

Photo by Tyler Lastovich on Unsplash