168854f4eSAhmed Bougacha# Pointer Authentication 268854f4eSAhmed Bougacha 368854f4eSAhmed Bougacha## Introduction 468854f4eSAhmed Bougacha 568854f4eSAhmed BougachaPointer Authentication is a mechanism by which certain pointers are signed. 668854f4eSAhmed BougachaWhen a pointer gets signed, a cryptographic hash of its value and other values 768854f4eSAhmed Bougacha(pepper and salt) is stored in unused bits of that pointer. 868854f4eSAhmed Bougacha 968854f4eSAhmed BougachaBefore the pointer is used, it needs to be authenticated, i.e., have its 1068854f4eSAhmed Bougachasignature checked. This prevents pointer values of unknown origin from being 1168854f4eSAhmed Bougachaused to replace the signed pointer value. 1268854f4eSAhmed Bougacha 130481f049SAhmed BougachaFor more details, see the clang documentation page for 140481f049SAhmed Bougacha[Pointer Authentication](https://clang.llvm.org/docs/PointerAuthentication.html). 150481f049SAhmed Bougacha 16c703f852SAhmed BougachaAt the IR level, it is represented using: 17c703f852SAhmed Bougacha 18c703f852SAhmed Bougacha* a [set of intrinsics](#intrinsics) (to sign/authenticate pointers) 190edc97f1SAhmed Bougacha* a [signed pointer constant](#constant) (to sign globals) 20c703f852SAhmed Bougacha* a [call operand bundle](#operand-bundle) (to authenticate called pointers) 21b8721fa0SAhmed Bougacha* a [set of function attributes](#function-attributes) (to describe what 22b8721fa0SAhmed Bougacha pointers are signed and how, to control implicit codegen in the backend, as 23b8721fa0SAhmed Bougacha well as preserve invariants in the mid-level optimizer) 2468854f4eSAhmed Bougacha 2568854f4eSAhmed BougachaThe current implementation leverages the 2668854f4eSAhmed Bougacha[Armv8.3-A PAuth/Pointer Authentication Code](#armv8-3-a-pauth-pointer-authentication-code) 2768854f4eSAhmed Bougachainstructions in the [AArch64 backend](#aarch64-support). 2868854f4eSAhmed BougachaThis support is used to implement the Darwin arm64e ABI, as well as the 2968854f4eSAhmed Bougacha[PAuth ABI Extension to ELF](https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst). 3068854f4eSAhmed Bougacha 3168854f4eSAhmed Bougacha 3268854f4eSAhmed Bougacha## LLVM IR Representation 3368854f4eSAhmed Bougacha 3468854f4eSAhmed Bougacha### Intrinsics 3568854f4eSAhmed Bougacha 3668854f4eSAhmed BougachaThese intrinsics are provided by LLVM to expose pointer authentication 3768854f4eSAhmed Bougachaoperations. 3868854f4eSAhmed Bougacha 3968854f4eSAhmed Bougacha 40c5861378SDaniil Kovalev#### '`llvm.ptrauth.sign`' 4168854f4eSAhmed Bougacha 4268854f4eSAhmed Bougacha##### Syntax: 4368854f4eSAhmed Bougacha 4468854f4eSAhmed Bougacha```llvm 4568854f4eSAhmed Bougachadeclare i64 @llvm.ptrauth.sign(i64 <value>, i32 <key>, i64 <discriminator>) 4668854f4eSAhmed Bougacha``` 4768854f4eSAhmed Bougacha 4868854f4eSAhmed Bougacha##### Overview: 4968854f4eSAhmed Bougacha 50c5861378SDaniil KovalevThe '`llvm.ptrauth.sign`' intrinsic signs a raw pointer. 5168854f4eSAhmed Bougacha 5268854f4eSAhmed Bougacha 5368854f4eSAhmed Bougacha##### Arguments: 5468854f4eSAhmed Bougacha 55c5861378SDaniil KovalevThe `value` argument is the raw pointer value to be signed. 56c5861378SDaniil KovalevThe `key` argument is the identifier of the key to be used to generate the 5768854f4eSAhmed Bougachasigned value. 58c5861378SDaniil KovalevThe `discriminator` argument is the additional diversity data to be used as a 5968854f4eSAhmed Bougachadiscriminator (an integer, an address, or a blend of the two). 6068854f4eSAhmed Bougacha 6168854f4eSAhmed Bougacha##### Semantics: 6268854f4eSAhmed Bougacha 63c5861378SDaniil KovalevThe '`llvm.ptrauth.sign`' intrinsic implements the `sign`_ operation. 6468854f4eSAhmed BougachaIt returns a signed value. 6568854f4eSAhmed Bougacha 66c5861378SDaniil KovalevIf `value` is already a signed value, the behavior is undefined. 6768854f4eSAhmed Bougacha 68c5861378SDaniil KovalevIf `value` is not a pointer value for which `key` is appropriate, the 6968854f4eSAhmed Bougachabehavior is undefined. 7068854f4eSAhmed Bougacha 7168854f4eSAhmed Bougacha 72c5861378SDaniil Kovalev#### '`llvm.ptrauth.auth`' 7368854f4eSAhmed Bougacha 7468854f4eSAhmed Bougacha##### Syntax: 7568854f4eSAhmed Bougacha 7668854f4eSAhmed Bougacha```llvm 7768854f4eSAhmed Bougachadeclare i64 @llvm.ptrauth.auth(i64 <value>, i32 <key>, i64 <discriminator>) 7868854f4eSAhmed Bougacha``` 7968854f4eSAhmed Bougacha 8068854f4eSAhmed Bougacha##### Overview: 8168854f4eSAhmed Bougacha 82c5861378SDaniil KovalevThe '`llvm.ptrauth.auth`' intrinsic authenticates a signed pointer. 8368854f4eSAhmed Bougacha 8468854f4eSAhmed Bougacha##### Arguments: 8568854f4eSAhmed Bougacha 86c5861378SDaniil KovalevThe `value` argument is the signed pointer value to be authenticated. 87c5861378SDaniil KovalevThe `key` argument is the identifier of the key that was used to generate 8868854f4eSAhmed Bougachathe signed value. 89c5861378SDaniil KovalevThe `discriminator` argument is the additional diversity data to be used as a 9068854f4eSAhmed Bougachadiscriminator. 9168854f4eSAhmed Bougacha 9268854f4eSAhmed Bougacha##### Semantics: 9368854f4eSAhmed Bougacha 94c5861378SDaniil KovalevThe '`llvm.ptrauth.auth`' intrinsic implements the `auth`_ operation. 9568854f4eSAhmed BougachaIt returns a raw pointer value. 96c5861378SDaniil KovalevIf `value` does not have a correct signature for `key` and `discriminator`, 9768854f4eSAhmed Bougachathe intrinsic traps in a target-specific way. 9868854f4eSAhmed Bougacha 9968854f4eSAhmed Bougacha 100c5861378SDaniil Kovalev#### '`llvm.ptrauth.strip`' 10168854f4eSAhmed Bougacha 10268854f4eSAhmed Bougacha##### Syntax: 10368854f4eSAhmed Bougacha 10468854f4eSAhmed Bougacha```llvm 10568854f4eSAhmed Bougachadeclare i64 @llvm.ptrauth.strip(i64 <value>, i32 <key>) 10668854f4eSAhmed Bougacha``` 10768854f4eSAhmed Bougacha 10868854f4eSAhmed Bougacha##### Overview: 10968854f4eSAhmed Bougacha 110c5861378SDaniil KovalevThe '`llvm.ptrauth.strip`' intrinsic strips the embedded signature out of a 11168854f4eSAhmed Bougachapossibly-signed pointer. 11268854f4eSAhmed Bougacha 11368854f4eSAhmed Bougacha 11468854f4eSAhmed Bougacha##### Arguments: 11568854f4eSAhmed Bougacha 116c5861378SDaniil KovalevThe `value` argument is the signed pointer value to be stripped. 117c5861378SDaniil KovalevThe `key` argument is the identifier of the key that was used to generate 11868854f4eSAhmed Bougachathe signed value. 11968854f4eSAhmed Bougacha 12068854f4eSAhmed Bougacha##### Semantics: 12168854f4eSAhmed Bougacha 122c5861378SDaniil KovalevThe '`llvm.ptrauth.strip`' intrinsic implements the `strip`_ operation. 12368854f4eSAhmed BougachaIt returns a raw pointer value. It does **not** check that the 12468854f4eSAhmed Bougachasignature is valid. 12568854f4eSAhmed Bougacha 126c5861378SDaniil Kovalev`key` should identify a key that is appropriate for `value`, as defined 1276989c484Scor3ntinby the target-specific [keys](#keys)). 12868854f4eSAhmed Bougacha 129c5861378SDaniil KovalevIf `value` is a raw pointer value, it is returned as-is (provided the `key` 13068854f4eSAhmed Bougachais appropriate for the pointer). 13168854f4eSAhmed Bougacha 132c5861378SDaniil KovalevIf `value` is not a pointer value for which `key` is appropriate, the 13368854f4eSAhmed Bougachabehavior is target-specific. 13468854f4eSAhmed Bougacha 135c5861378SDaniil KovalevIf `value` is a signed pointer value, but `key` does not identify the 136c5861378SDaniil Kovalevsame key that was used to generate `value`, the behavior is 13768854f4eSAhmed Bougachatarget-specific. 13868854f4eSAhmed Bougacha 13968854f4eSAhmed Bougacha 140c5861378SDaniil Kovalev#### '`llvm.ptrauth.resign`' 14168854f4eSAhmed Bougacha 14268854f4eSAhmed Bougacha##### Syntax: 14368854f4eSAhmed Bougacha 14468854f4eSAhmed Bougacha```llvm 14568854f4eSAhmed Bougachadeclare i64 @llvm.ptrauth.resign(i64 <value>, 14668854f4eSAhmed Bougacha i32 <old key>, i64 <old discriminator>, 14768854f4eSAhmed Bougacha i32 <new key>, i64 <new discriminator>) 14868854f4eSAhmed Bougacha``` 14968854f4eSAhmed Bougacha 15068854f4eSAhmed Bougacha##### Overview: 15168854f4eSAhmed Bougacha 152c5861378SDaniil KovalevThe '`llvm.ptrauth.resign`' intrinsic re-signs a signed pointer using 15368854f4eSAhmed Bougachaa different key and diversity data. 15468854f4eSAhmed Bougacha 15568854f4eSAhmed Bougacha##### Arguments: 15668854f4eSAhmed Bougacha 157c5861378SDaniil KovalevThe `value` argument is the signed pointer value to be authenticated. 158c5861378SDaniil KovalevThe `old key` argument is the identifier of the key that was used to generate 15968854f4eSAhmed Bougachathe signed value. 160c5861378SDaniil KovalevThe `old discriminator` argument is the additional diversity data to be used 16168854f4eSAhmed Bougachaas a discriminator in the auth operation. 162c5861378SDaniil KovalevThe `new key` argument is the identifier of the key to use to generate the 16368854f4eSAhmed Bougacharesigned value. 164c5861378SDaniil KovalevThe `new discriminator` argument is the additional diversity data to be used 16568854f4eSAhmed Bougachaas a discriminator in the sign operation. 16668854f4eSAhmed Bougacha 16768854f4eSAhmed Bougacha##### Semantics: 16868854f4eSAhmed Bougacha 169c5861378SDaniil KovalevThe '`llvm.ptrauth.resign`' intrinsic performs a combined `auth`_ and `sign`_ 17068854f4eSAhmed Bougachaoperation, without exposing the intermediate raw pointer. 17168854f4eSAhmed BougachaIt returns a signed pointer value. 172c5861378SDaniil KovalevIf `value` does not have a correct signature for `old key` and 173c5861378SDaniil Kovalev`old discriminator`, the intrinsic traps in a target-specific way. 17468854f4eSAhmed Bougacha 175c5861378SDaniil Kovalev#### '`llvm.ptrauth.sign_generic`' 17668854f4eSAhmed Bougacha 17768854f4eSAhmed Bougacha##### Syntax: 17868854f4eSAhmed Bougacha 17968854f4eSAhmed Bougacha```llvm 18068854f4eSAhmed Bougachadeclare i64 @llvm.ptrauth.sign_generic(i64 <value>, i64 <discriminator>) 18168854f4eSAhmed Bougacha``` 18268854f4eSAhmed Bougacha 18368854f4eSAhmed Bougacha##### Overview: 18468854f4eSAhmed Bougacha 185c5861378SDaniil KovalevThe '`llvm.ptrauth.sign_generic`' intrinsic computes a generic signature of 18668854f4eSAhmed Bougachaarbitrary data. 18768854f4eSAhmed Bougacha 18868854f4eSAhmed Bougacha##### Arguments: 18968854f4eSAhmed Bougacha 190c5861378SDaniil KovalevThe `value` argument is the arbitrary data value to be signed. 191c5861378SDaniil KovalevThe `discriminator` argument is the additional diversity data to be used as a 19268854f4eSAhmed Bougachadiscriminator. 19368854f4eSAhmed Bougacha 19468854f4eSAhmed Bougacha##### Semantics: 19568854f4eSAhmed Bougacha 196c5861378SDaniil KovalevThe '`llvm.ptrauth.sign_generic`' intrinsic computes the signature of a given 19768854f4eSAhmed Bougachacombination of value and additional diversity data. 19868854f4eSAhmed Bougacha 19968854f4eSAhmed BougachaIt returns a full signature value (as opposed to a signed pointer value, with 20068854f4eSAhmed Bougachaan embedded partial signature). 20168854f4eSAhmed Bougacha 202c5861378SDaniil KovalevAs opposed to [`llvm.ptrauth.sign`](#llvm-ptrauth-sign), it does not interpret 203c5861378SDaniil Kovalev`value` as a pointer value. Instead, it is an arbitrary data value. 20468854f4eSAhmed Bougacha 20568854f4eSAhmed Bougacha 206c5861378SDaniil Kovalev#### '`llvm.ptrauth.blend`' 20768854f4eSAhmed Bougacha 20868854f4eSAhmed Bougacha##### Syntax: 20968854f4eSAhmed Bougacha 21068854f4eSAhmed Bougacha```llvm 21168854f4eSAhmed Bougachadeclare i64 @llvm.ptrauth.blend(i64 <address discriminator>, i64 <integer discriminator>) 21268854f4eSAhmed Bougacha``` 21368854f4eSAhmed Bougacha 21468854f4eSAhmed Bougacha##### Overview: 21568854f4eSAhmed Bougacha 216c5861378SDaniil KovalevThe '`llvm.ptrauth.blend`' intrinsic blends a pointer address discriminator 21768854f4eSAhmed Bougachawith a small integer discriminator to produce a new "blended" discriminator. 21868854f4eSAhmed Bougacha 21968854f4eSAhmed Bougacha##### Arguments: 22068854f4eSAhmed Bougacha 221c5861378SDaniil KovalevThe `address discriminator` argument is a pointer value. 222c5861378SDaniil KovalevThe `integer discriminator` argument is a small integer, as specified by the 22368854f4eSAhmed Bougachatarget. 22468854f4eSAhmed Bougacha 22568854f4eSAhmed Bougacha##### Semantics: 22668854f4eSAhmed Bougacha 227c5861378SDaniil KovalevThe '`llvm.ptrauth.blend`' intrinsic combines a small integer discriminator 22868854f4eSAhmed Bougachawith a pointer address discriminator, in a way that is specified by the target 22968854f4eSAhmed Bougachaimplementation. 23068854f4eSAhmed Bougacha 23168854f4eSAhmed Bougacha 2320edc97f1SAhmed Bougacha### Constant 2330edc97f1SAhmed Bougacha 2340edc97f1SAhmed Bougacha[Intrinsics](#intrinsics) can be used to produce signed pointers dynamically, 2350edc97f1SAhmed Bougachain code, but not for signed pointers referenced by constants, in, e.g., global 2360edc97f1SAhmed Bougachainitializers. 2370edc97f1SAhmed Bougacha 2380edc97f1SAhmed BougachaThe latter are represented using a 2390edc97f1SAhmed Bougacha[``ptrauth`` constant](https://llvm.org/docs/LangRef.html#ptrauth-constant), 2400edc97f1SAhmed Bougachawhich describes an authenticated relocation producing a signed pointer. 2410edc97f1SAhmed Bougacha 2420edc97f1SAhmed Bougacha```llvm 2430edc97f1SAhmed Bougachaptrauth (ptr CST, i32 KEY, i64 DISC, ptr ADDRDISC) 2440edc97f1SAhmed Bougacha``` 2450edc97f1SAhmed Bougacha 2460edc97f1SAhmed Bougachais equivalent to: 2470edc97f1SAhmed Bougacha 2480edc97f1SAhmed Bougacha```llvm 2490edc97f1SAhmed Bougacha %disc = call i64 @llvm.ptrauth.blend(i64 ptrtoint(ptr ADDRDISC to i64), i64 DISC) 2500edc97f1SAhmed Bougacha %signedval = call i64 @llvm.ptrauth.sign(ptr CST, i32 KEY, i64 %disc) 2510edc97f1SAhmed Bougacha``` 2520edc97f1SAhmed Bougacha 253c703f852SAhmed Bougacha### Operand Bundle 254c703f852SAhmed Bougacha 255c703f852SAhmed BougachaFunction pointers used as indirect call targets can be signed when materialized, 256c703f852SAhmed Bougachaand authenticated before calls. This can be accomplished with the 257c5861378SDaniil Kovalev[`llvm.ptrauth.auth`](#llvm-ptrauth-auth) intrinsic, feeding its result to 258c703f852SAhmed Bougachaan indirect call. 259c703f852SAhmed Bougacha 260c703f852SAhmed BougachaHowever, that exposes the intermediate, unauthenticated pointer, e.g., if it 261c703f852SAhmed Bougachagets spilled to the stack. An attacker can then overwrite the pointer in 262c703f852SAhmed Bougachamemory, negating the security benefit provided by pointer authentication. 263c5861378SDaniil KovalevTo prevent that, the `ptrauth` operand bundle may be used: it guarantees that 264c703f852SAhmed Bougachathe intermediate call target is kept in a register and never stored to memory. 265c703f852SAhmed BougachaThis hardening benefit is similar to that provided by 266c5861378SDaniil Kovalev[`llvm.ptrauth.resign`](#llvm-ptrauth-resign)). 267c703f852SAhmed Bougacha 268c703f852SAhmed BougachaConcretely: 269c703f852SAhmed Bougacha 270c703f852SAhmed Bougacha```llvm 271c703f852SAhmed Bougachadefine void @f(void ()* %fp) { 272c703f852SAhmed Bougacha call void %fp() [ "ptrauth"(i32 <key>, i64 <data>) ] 273c703f852SAhmed Bougacha ret void 274c703f852SAhmed Bougacha} 275c703f852SAhmed Bougacha``` 276c703f852SAhmed Bougacha 277c703f852SAhmed Bougachais functionally equivalent to: 278c703f852SAhmed Bougacha 279c703f852SAhmed Bougacha```llvm 280c703f852SAhmed Bougachadefine void @f(void ()* %fp) { 281c703f852SAhmed Bougacha %fp_i = ptrtoint void ()* %fp to i64 282c703f852SAhmed Bougacha %fp_auth = call i64 @llvm.ptrauth.auth(i64 %fp_i, i32 <key>, i64 <data>) 283c703f852SAhmed Bougacha %fp_auth_p = inttoptr i64 %fp_auth to void ()* 284c703f852SAhmed Bougacha call void %fp_auth_p() 285c703f852SAhmed Bougacha ret void 286c703f852SAhmed Bougacha} 287c703f852SAhmed Bougacha``` 288c703f852SAhmed Bougacha 289c5861378SDaniil Kovalevbut with the added guarantee that `%fp_i`, `%fp_auth`, and `%fp_auth_p` 290c703f852SAhmed Bougachaare not stored to (and reloaded from) memory. 291c703f852SAhmed Bougacha 292c703f852SAhmed Bougacha 293b8721fa0SAhmed Bougacha### Function Attributes 294b8721fa0SAhmed Bougacha 295b8721fa0SAhmed BougachaSome function attributes are used to describe other pointer authentication 296b8721fa0SAhmed Bougachaoperations that are not otherwise explicitly expressed in IR. 297b8721fa0SAhmed Bougacha 298b8721fa0SAhmed Bougacha#### ``ptrauth-indirect-gotos`` 299b8721fa0SAhmed Bougacha 300b8721fa0SAhmed Bougacha``ptrauth-indirect-gotos`` specifies that indirect gotos in this function 301b8721fa0SAhmed Bougachashould authenticate their target. At the IR level, no other change is needed. 302b8721fa0SAhmed BougachaWhen lowering [``blockaddress`` constants](https://llvm.org/docs/LangRef.html#blockaddress), 303b8721fa0SAhmed Bougachaand [``indirectbr`` instructions](https://llvm.org/docs/LangRef.html#i-indirectbr), 304b8721fa0SAhmed Bougachathis tells the backend to respectively sign and authenticate the pointers. 305b8721fa0SAhmed Bougacha 306b8721fa0SAhmed BougachaThe specific scheme isn't ABI-visible. Currently, the AArch64 backend 307b8721fa0SAhmed Bougachasigns blockaddresses using the `ASIA` key, with an integer discriminator 308b8721fa0SAhmed Bougachaderived from the parent function's name, using the SipHash stable discriminator: 309b8721fa0SAhmed Bougacha``` 310b8721fa0SAhmed Bougacha ptrauth_string_discriminator("<function_name> blockaddress") 311b8721fa0SAhmed Bougacha``` 312b8721fa0SAhmed Bougacha 313b8721fa0SAhmed Bougacha 31468854f4eSAhmed Bougacha## AArch64 Support 31568854f4eSAhmed Bougacha 31668854f4eSAhmed BougachaAArch64 is currently the only architecture with full support of the pointer 31768854f4eSAhmed Bougachaauthentication primitives, based on Armv8.3-A instructions. 31868854f4eSAhmed Bougacha 31968854f4eSAhmed Bougacha### Armv8.3-A PAuth Pointer Authentication Code 32068854f4eSAhmed Bougacha 32168854f4eSAhmed BougachaThe Armv8.3-A architecture extension defines the PAuth feature, which provides 32268854f4eSAhmed Bougachasupport for instructions that manipulate Pointer Authentication Codes (PAC). 32368854f4eSAhmed Bougacha 32468854f4eSAhmed Bougacha#### Keys 32568854f4eSAhmed Bougacha 32668854f4eSAhmed Bougacha5 keys are supported by the PAuth feature. 32768854f4eSAhmed Bougacha 32868854f4eSAhmed BougachaOf those, 4 keys are interchangeably usable to specify the key used in IR 32968854f4eSAhmed Bougachaconstructs: 330c5861378SDaniil Kovalev* `ASIA`/`ASIB` are instruction keys (encoded as respectively 0 and 1). 331c5861378SDaniil Kovalev* `ASDA`/`ASDB` are data keys (encoded as respectively 2 and 3). 33268854f4eSAhmed Bougacha 333c5861378SDaniil Kovalev`ASGA` is a special key that cannot be explicitly specified, and is only ever 33468854f4eSAhmed Bougachaused implicitly, to implement the 335c5861378SDaniil Kovalev[`llvm.ptrauth.sign_generic`](#llvm-ptrauth-sign-generic) intrinsic. 33668854f4eSAhmed Bougacha 33768854f4eSAhmed Bougacha#### Instructions 33868854f4eSAhmed Bougacha 33968854f4eSAhmed BougachaThe IR [Intrinsics](#intrinsics) described above map onto these 34068854f4eSAhmed Bougachainstructions as such: 341c5861378SDaniil Kovalev* [`llvm.ptrauth.sign`](#llvm-ptrauth-sign): `PAC{I,D}{A,B}{Z,SP,}` 342c5861378SDaniil Kovalev* [`llvm.ptrauth.auth`](#llvm-ptrauth-auth): `AUT{I,D}{A,B}{Z,SP,}` 343c5861378SDaniil Kovalev* [`llvm.ptrauth.strip`](#llvm-ptrauth-strip): `XPAC{I,D}` 344c5861378SDaniil Kovalev* [`llvm.ptrauth.blend`](#llvm-ptrauth-blend): The semantics of the blend 34568854f4eSAhmed Bougacha operation are specified by the ABI. In both the ELF PAuth ABI Extension and 346c5861378SDaniil Kovalev arm64e, it's a `MOVK` into the high 16 bits. Consequently, this limits 34768854f4eSAhmed Bougacha the width of the integer discriminator used in blends to 16 bits. 348c5861378SDaniil Kovalev* [`llvm.ptrauth.sign_generic`](#llvm-ptrauth-sign-generic): `PACGA` 349c5861378SDaniil Kovalev* [`llvm.ptrauth.resign`](#llvm-ptrauth-resign): `AUT*+PAC*`. These are 35068854f4eSAhmed Bougacha represented as a single pseudo-instruction in the backend to guarantee that 35168854f4eSAhmed Bougacha the intermediate raw pointer value is not spilled and attackable. 35256ad9e91SDaniil Kovalev 35356ad9e91SDaniil Kovalev#### Assembly Representation 35456ad9e91SDaniil Kovalev 355d97947e1SAiden GrossmanAt the assembly level, authenticated relocations are represented 35656ad9e91SDaniil Kovalevusing the `@AUTH` modifier: 35756ad9e91SDaniil Kovalev 35856ad9e91SDaniil Kovalev```asm 35956ad9e91SDaniil Kovalev .quad _target@AUTH(<key>,<discriminator>[,addr]) 36056ad9e91SDaniil Kovalev``` 36156ad9e91SDaniil Kovalev 36256ad9e91SDaniil Kovalevwhere: 36356ad9e91SDaniil Kovalev* `key` is the Armv8.3-A key identifier (`ia`, `ib`, `da`, `db`) 36456ad9e91SDaniil Kovalev* `discriminator` is the 16-bit unsigned discriminator value 36556ad9e91SDaniil Kovalev* `addr` signifies that the authenticated pointer is address-discriminated 36656ad9e91SDaniil Kovalev (that is, that the relocation's target address is to be blended into the 36756ad9e91SDaniil Kovalev `discriminator` before it is used in the sign operation. 36856ad9e91SDaniil Kovalev 36956ad9e91SDaniil KovalevFor example: 37056ad9e91SDaniil Kovalev```asm 37156ad9e91SDaniil Kovalev _authenticated_reference_to_sym: 37256ad9e91SDaniil Kovalev .quad _sym@AUTH(db,0) 37356ad9e91SDaniil Kovalev _authenticated_reference_to_sym_addr_disc: 37456ad9e91SDaniil Kovalev .quad _sym@AUTH(ia,12,addr) 37556ad9e91SDaniil Kovalev``` 37656ad9e91SDaniil Kovalev 377*464fa3b3SAhmed Bougacha#### MachO Object File Representation 378*464fa3b3SAhmed Bougacha 379*464fa3b3SAhmed BougachaAt the object file level, authenticated relocations are represented using the 380*464fa3b3SAhmed Bougacha``ARM64_RELOC_AUTHENTICATED_POINTER`` relocation kind (with value ``11``). 381*464fa3b3SAhmed Bougacha 382*464fa3b3SAhmed BougachaThe pointer authentication information is encoded into the addend as follows: 383*464fa3b3SAhmed Bougacha 384*464fa3b3SAhmed Bougacha``` 385*464fa3b3SAhmed Bougacha| 63 | 62 | 61-51 | 50-49 | 48 | 47 - 32 | 31 - 0 | 386*464fa3b3SAhmed Bougacha| -- | -- | ----- | ----- | ------ | --------------- | -------- | 387*464fa3b3SAhmed Bougacha| 1 | 0 | 0 | key | addr | discriminator | addend | 388*464fa3b3SAhmed Bougacha``` 389*464fa3b3SAhmed Bougacha 39056ad9e91SDaniil Kovalev#### ELF Object File Representation 39156ad9e91SDaniil Kovalev 392d97947e1SAiden GrossmanAt the object file level, authenticated relocations are represented 39356ad9e91SDaniil Kovalevusing the `R_AARCH64_AUTH_ABS64` relocation kind (with value `0xE100`). 39456ad9e91SDaniil Kovalev 39556ad9e91SDaniil KovalevThe signing schema is encoded in the place of relocation to be applied 39656ad9e91SDaniil Kovalevas follows: 39756ad9e91SDaniil Kovalev 39856ad9e91SDaniil Kovalev``` 39956ad9e91SDaniil Kovalev| 63 | 62 | 61:60 | 59:48 | 47:32 | 31:0 | 40056ad9e91SDaniil Kovalev| ----------------- | -------- | -------- | -------- | ------------- | ------------------- | 40156ad9e91SDaniil Kovalev| address diversity | reserved | key | reserved | discriminator | reserved for addend | 40256ad9e91SDaniil Kovalev``` 403