xref: /llvm-project/llvm/docs/PointerAuth.md (revision 464fa3b3b047518699689b57c473c87701986593)
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