clang 19.0.0git
ptrauth.h
Go to the documentation of this file.
1/*===---- ptrauth.h - Pointer authentication -------------------------------===
2 *
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 *
7 *===-----------------------------------------------------------------------===
8 */
9
10#ifndef __PTRAUTH_H
11#define __PTRAUTH_H
12
13typedef enum {
19
20/* An integer type of the appropriate size for a discriminator argument. */
21typedef __UINTPTR_TYPE__ ptrauth_extra_data_t;
22
23/* An integer type of the appropriate size for a generic signature. */
24typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
25
26/* A signed pointer value embeds the original pointer together with
27 a signature that attests to the validity of that pointer. Because
28 this signature must use only "spare" bits of the pointer, a
29 signature's validity is probabilistic in practice: it is unlikely
30 but still plausible that an invalidly-derived signature will
31 somehow equal the correct signature and therefore successfully
32 authenticate. Nonetheless, this scheme provides a strong degree
33 of protection against certain kinds of attacks. */
34
35/* Authenticating a pointer that was not signed with the given key
36 and extra-data value will (likely) fail by trapping. */
37
38#if __has_feature(ptrauth_intrinsics)
39
40/* Strip the signature from a value without authenticating it.
41
42 If the value is a function pointer, the result will not be a
43 legal function pointer because of the missing signature, and
44 attempting to call it will result in an authentication failure.
45
46 The value must be an expression of pointer type.
47 The key must be a constant expression of type ptrauth_key.
48 The result will have the same type as the original value. */
49#define ptrauth_strip(__value, __key) __builtin_ptrauth_strip(__value, __key)
50
51/* Blend a constant discriminator into the given pointer-like value
52 to form a new discriminator. Not all bits of the inputs are
53 guaranteed to contribute to the result.
54
55 On arm64e, the integer must fall within the range of a uint16_t;
56 other bits may be ignored.
57
58 The first argument must be an expression of pointer type.
59 The second argument must be an expression of integer type.
60 The result will have type uintptr_t. */
61#define ptrauth_blend_discriminator(__pointer, __integer) \
62 __builtin_ptrauth_blend_discriminator(__pointer, __integer)
63
64/* Add a signature to the given pointer value using a specific key,
65 using the given extra data as a salt to the signing process.
66
67 This operation does not authenticate the original value and is
68 therefore potentially insecure if an attacker could possibly
69 control that value.
70
71 The value must be an expression of pointer type.
72 The key must be a constant expression of type ptrauth_key.
73 The extra data must be an expression of pointer or integer type;
74 if an integer, it will be coerced to ptrauth_extra_data_t.
75 The result will have the same type as the original value. */
76#define ptrauth_sign_unauthenticated(__value, __key, __data) \
77 __builtin_ptrauth_sign_unauthenticated(__value, __key, __data)
78
79/* Authenticate a pointer using one scheme and resign it using another.
80
81 If the result is subsequently authenticated using the new scheme, that
82 authentication is guaranteed to fail if and only if the initial
83 authentication failed.
84
85 The value must be an expression of pointer type.
86 The key must be a constant expression of type ptrauth_key.
87 The extra data must be an expression of pointer or integer type;
88 if an integer, it will be coerced to ptrauth_extra_data_t.
89 The result will have the same type as the original value.
90
91 This operation is guaranteed to not leave the intermediate value
92 available for attack before it is re-signed.
93
94 Do not pass a null pointer to this function. A null pointer
95 will not successfully authenticate.
96
97 This operation traps if the authentication fails. */
98#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, \
99 __new_data) \
100 __builtin_ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, \
101 __new_data)
102
103/* Authenticate a data pointer.
104
105 The value must be an expression of non-function pointer type.
106 The key must be a constant expression of type ptrauth_key.
107 The extra data must be an expression of pointer or integer type;
108 if an integer, it will be coerced to ptrauth_extra_data_t.
109 The result will have the same type as the original value.
110
111 This operation traps if the authentication fails. */
112#define ptrauth_auth_data(__value, __old_key, __old_data) \
113 __builtin_ptrauth_auth(__value, __old_key, __old_data)
114
115/* Compute a signature for the given pair of pointer-sized values.
116 The order of the arguments is significant.
117
118 Like a pointer signature, the resulting signature depends on
119 private key data and therefore should not be reliably reproducible
120 by attackers. That means that this can be used to validate the
121 integrity of arbitrary data by storing a signature for that data
122 alongside it, then checking that the signature is still valid later.
123 Data which exceeds two pointers in size can be signed by either
124 computing a tree of generic signatures or just signing an ordinary
125 cryptographic hash of the data.
126
127 The result has type ptrauth_generic_signature_t. However, it may
128 not have as many bits of entropy as that type's width would suggest;
129 some implementations are known to compute a compressed signature as
130 if the arguments were a pointer and a discriminator.
131
132 The arguments must be either pointers or integers; if integers, they
133 will be coerce to uintptr_t. */
134#define ptrauth_sign_generic_data(__value, __data) \
135 __builtin_ptrauth_sign_generic_data(__value, __data)
136
137#else
138
139#define ptrauth_strip(__value, __key) \
140 ({ \
141 (void)__key; \
142 __value; \
143 })
144
145#define ptrauth_blend_discriminator(__pointer, __integer) \
146 ({ \
147 (void)__pointer; \
148 (void)__integer; \
149 ((ptrauth_extra_data_t)0); \
150 })
151
152#define ptrauth_sign_unauthenticated(__value, __key, __data) \
153 ({ \
154 (void)__key; \
155 (void)__data; \
156 __value; \
157 })
158
159#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, \
160 __new_data) \
161 ({ \
162 (void)__old_key; \
163 (void)__old_data; \
164 (void)__new_key; \
165 (void)__new_data; \
166 __value; \
167 })
168
169#define ptrauth_auth_data(__value, __old_key, __old_data) \
170 ({ \
171 (void)__old_key; \
172 (void)__old_data; \
173 __value; \
174 })
175
176#define ptrauth_sign_generic_data(__value, __data) \
177 ({ \
178 (void)__value; \
179 (void)__data; \
180 ((ptrauth_generic_signature_t)0); \
181 })
182
183#endif /* __has_feature(ptrauth_intrinsics) */
184
185#endif /* __PTRAUTH_H */
__UINTPTR_TYPE__ ptrauth_extra_data_t
Definition: ptrauth.h:21
__UINTPTR_TYPE__ ptrauth_generic_signature_t
Definition: ptrauth.h:24
ptrauth_key
Definition: ptrauth.h:13
@ ptrauth_key_asia
Definition: ptrauth.h:14
@ ptrauth_key_asda
Definition: ptrauth.h:16
@ ptrauth_key_asib
Definition: ptrauth.h:15
@ ptrauth_key_asdb
Definition: ptrauth.h:17