1/*
2 * Copyright (c) 2020 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef __AMFI_H
30#define __AMFI_H
31
32#include <os/base.h>
33#include <sys/cdefs.h>
34#include <kern/cs_blobs.h>
35
36#define KERN_AMFI_INTERFACE_VERSION 6
37#define KERN_AMFI_SUPPORTS_DATA_ALLOC 2
38
39#pragma mark Forward Declarations
40struct proc;
41struct cs_blob;
42
43#pragma mark Type Defines
44typedef struct proc* proc_t;
45
46#if XNU_KERNEL_PRIVATE
47#ifndef CORE_ENTITLEMENTS_I_KNOW_WHAT_IM_DOING
48#define CORE_ENTITLEMENTS_I_KNOW_WHAT_IM_DOING
49#endif
50
51#include <CoreEntitlements/CoreEntitlementsPriv.h>
52#endif
53
54typedef void (*amfi_OSEntitlements_invalidate)(void* osentitlements);
55typedef void* (*amfi_OSEntitlements_asDict)(void* osentitlements);
56typedef CEError_t (*amfi_OSEntitlements_query)(void* osentitlements, uint8_t cdhash[CS_CDHASH_LEN], CEQuery_t query, size_t queryLength);
57typedef bool (*amfi_OSEntitlements_get_transmuted_blob)(void* osentitlements, const CS_GenericBlob **blob);
58typedef bool (*amfi_OSEntitlements_get_xml_blob)(void* osentitlements, CS_GenericBlob **blob);
59typedef bool (*amfi_get_legacy_profile_exemptions)(const uint8_t **profile, size_t *profileLength);
60typedef bool (*amfi_get_udid)(const uint8_t **udid, size_t *udidLength);
61typedef void* (*amfi_query_context_to_object)(CEQueryContext_t ctx);
62
63#pragma mark OSEntitlements
64
65#define KERN_AMFI_SUPPORTS_OSENTITLEMENTS_API 1
66#define OSENTITLEMENTS_INTERFACE_VERSION 1u
67
68typedef kern_return_t (*OSEntitlements_adjustContextWithMonitor)(
69 void* os_entitlements,
70 const CEQueryContext_t ce_ctx,
71 const void *monitor_sig_obj,
72 const char *identity,
73 const uint32_t code_signing_flags
74 );
75
76typedef kern_return_t (*OSEntitlements_adjustContextWithoutMonitor)(
77 void* os_entitlements,
78 struct cs_blob *code_signing_blob
79 );
80
81typedef kern_return_t (*OSEntitlements_queryEntitlementBoolean)(
82 const void *os_entitlements,
83 const char *entitlement_name
84 );
85
86typedef kern_return_t (*OSEntitlements_queryEntitlementBooleanWithProc)(
87 const proc_t proc,
88 const char *entitlement_name
89 );
90
91typedef kern_return_t (*OSEntitlements_queryEntitlementString)(
92 const void *os_entitlements,
93 const char *entitlement_name,
94 const char *entitlement_value
95 );
96
97typedef kern_return_t (*OSEntitlements_queryEntitlementStringWithProc)(
98 const proc_t proc,
99 const char *entitlement_name,
100 const char *entitlement_value
101 );
102
103typedef kern_return_t (*OSEntitlements_copyEntitlementAsOSObject)(
104 const void *os_entitlements,
105 const char *entitlement_name,
106 void **entitlement_object
107 );
108
109typedef kern_return_t (*OSEntitlements_copyEntitlementAsOSObjectWithProc)(
110 const proc_t proc,
111 const char *entitlement_name,
112 void **entitlement_object
113 );
114
115typedef struct _OSEntitlementsInterface {
116 uint32_t version;
117 OSEntitlements_adjustContextWithMonitor adjustContextWithMonitor;
118 OSEntitlements_adjustContextWithoutMonitor adjustContextWithoutMonitor;
119 OSEntitlements_queryEntitlementBoolean queryEntitlementBoolean;
120 OSEntitlements_queryEntitlementBooleanWithProc queryEntitlementBooleanWithProc;
121 OSEntitlements_queryEntitlementString queryEntitlementString;
122 OSEntitlements_queryEntitlementStringWithProc queryEntitlementStringWithProc;
123 OSEntitlements_copyEntitlementAsOSObject copyEntitlementAsOSObject;
124 OSEntitlements_copyEntitlementAsOSObjectWithProc copyEntitlementAsOSObjectWithProc;
125} OSEntitlementsInterface_t;
126
127#pragma mark libTrustCache
128
129#include <TrustCache/API.h>
130#define KERN_AMFI_SUPPORTS_TRUST_CACHE_API 1
131#define TRUST_CACHE_INTERFACE_VERSION 3u
132
133typedef TCReturn_t (*constructInvalid_t)(
134 TrustCache_t *trustCache,
135 const uint8_t *moduleAddr,
136 size_t moduleSize
137 );
138
139typedef TCReturn_t (*checkRuntimeForUUID_t)(
140 const TrustCacheRuntime_t *runtime,
141 const uint8_t checkUUID[kUUIDSize],
142 const TrustCache_t **trustCacheRet
143 );
144
145typedef TCReturn_t (*loadModule_t)(
146 TrustCacheRuntime_t *runtime,
147 const TCType_t type,
148 TrustCache_t *trustCache,
149 const uintptr_t dataAddr,
150 const size_t dataSize
151 );
152
153typedef TCReturn_t (*load_t)(
154 TrustCacheRuntime_t *runtime,
155 TCType_t type,
156 TrustCache_t *trustCache,
157 const uintptr_t payloadAddr,
158 const size_t payloadSize,
159 const uintptr_t manifestAddr,
160 const size_t manifestSize
161 );
162
163typedef TCReturn_t (*extractModule_t)(
164 TrustCache_t *trustCache,
165 const uint8_t *dataAddr,
166 size_t dataSize
167 );
168
169typedef TCReturn_t (*query_t)(
170 const TrustCacheRuntime_t *runtime,
171 TCQueryType_t queryType,
172 const uint8_t CDHash[kTCEntryHashSize],
173 TrustCacheQueryToken_t *queryToken
174 );
175
176typedef TCReturn_t (*getModule_t)(
177 const TrustCache_t *trustCache,
178 const uint8_t **moduleAddrRet,
179 size_t *moduleSizeRet
180 );
181
182typedef TCReturn_t (*getUUID_t)(
183 const TrustCache_t *trustCache,
184 uint8_t returnUUID[kUUIDSize]
185 );
186
187typedef TCReturn_t (*getCapabilities_t)(
188 const TrustCache_t *trustCache,
189 TCCapabilities_t *capabilities
190 );
191
192typedef TCReturn_t (*queryGetTCType_t)(
193 const TrustCacheQueryToken_t *queryToken,
194 TCType_t *typeRet
195 );
196
197typedef TCReturn_t (*queryGetCapabilities_t)(
198 const TrustCacheQueryToken_t *queryToken,
199 TCCapabilities_t *capabilities
200 );
201
202typedef TCReturn_t (*queryGetHashType_t)(
203 const TrustCacheQueryToken_t *queryToken,
204 uint8_t *hashTypeRet
205 );
206
207typedef TCReturn_t (*queryGetFlags_t)(
208 const TrustCacheQueryToken_t *queryToken,
209 uint64_t *flagsRet
210 );
211
212typedef TCReturn_t (*queryGetConstraintCategory_t)(
213 const TrustCacheQueryToken_t *queryToken,
214 uint8_t *constraintCategoryRet
215 );
216
217typedef struct _TrustCacheInterface {
218 uint32_t version;
219 loadModule_t loadModule;
220 load_t load;
221 query_t query;
222 getCapabilities_t getCapabilities;
223 queryGetTCType_t queryGetTCType;
224 queryGetCapabilities_t queryGetCapabilities;
225 queryGetHashType_t queryGetHashType;
226 queryGetFlags_t queryGetFlags;
227 queryGetConstraintCategory_t queryGetConstraintCategory;
228
229 /* Available since interface version 3 */
230 constructInvalid_t constructInvalid;
231 checkRuntimeForUUID_t checkRuntimeForUUID;
232 extractModule_t extractModule;
233 getModule_t getModule;
234 getUUID_t getUUID;
235} TrustCacheInterface_t;
236
237#pragma mark Main AMFI Structure
238
239typedef struct _amfi {
240 amfi_OSEntitlements_invalidate OSEntitlements_invalidate;
241 amfi_OSEntitlements_asDict OSEntitlements_asdict;
242 amfi_OSEntitlements_query OSEntitlements_query;
243 amfi_OSEntitlements_get_transmuted_blob OSEntitlements_get_transmuted;
244 amfi_OSEntitlements_get_xml_blob OSEntitlements_get_xml;
245 coreentitlements_t CoreEntitlements;
246 amfi_get_legacy_profile_exemptions get_legacy_profile_exemptions;
247 amfi_get_udid get_udid;
248 amfi_query_context_to_object query_context_to_object;
249
250#if KERN_AMFI_SUPPORTS_TRUST_CACHE_API
251 /* Interface to interact with libTrustCache */
252 TrustCacheInterface_t TrustCache;
253#endif
254
255#if KERN_AMFI_SUPPORTS_OSENTITLEMENTS_API
256 /* Interface to interact with OSEntitlements */
257 OSEntitlementsInterface_t OSEntitlements;
258#endif
259} amfi_t;
260
261__BEGIN_DECLS
262
263/*!
264 * @const amfi
265 * The AMFI interface that was registered.
266 */
267extern const amfi_t * amfi;
268
269/*!
270 * @function amfi_interface_register
271 * Registers the AMFI kext interface for use within the kernel proper.
272 *
273 * @param mfi
274 * The interface to register.
275 *
276 * @discussion
277 * This routine may only be called once and must be called before late-const has
278 * been applied to kernel memory.
279 */
280OS_EXPORT OS_NONNULL1
281void
282amfi_interface_register(const amfi_t *mfi);
283
284__END_DECLS
285
286#endif // __AMFI_H
287