1/*
2 * Copyright (c) 2022 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#ifndef _SYS_CODE_SIGNING_H_
24#define _SYS_CODE_SIGNING_H_
25
26#include <sys/cdefs.h>
27__BEGIN_DECLS
28
29#pragma GCC diagnostic push
30#pragma GCC diagnostic ignored "-Wnullability-completeness"
31#pragma GCC diagnostic ignored "-Wnullability-completeness-on-arrays"
32
33typedef uint32_t code_signing_monitor_type_t;
34enum {
35 CS_MONITOR_TYPE_NONE = 0,
36 CS_MONITOR_TYPE_PPL = 1,
37 CS_MONITOR_TYPE_TXM = 2
38};
39
40typedef uint32_t code_signing_config_t;
41enum {
42 /* Exemptions */
43 CS_CONFIG_UNRESTRICTED_DEBUGGING = (1 << 0),
44 CS_CONFIG_ALLOW_ANY_SIGNATURE = (1 << 1),
45 CS_CONFIG_ENFORCEMENT_DISABLED = (1 << 2),
46 CS_CONFIG_GET_OUT_OF_MY_WAY = (1 << 3),
47 CS_CONFIG_INTEGRITY_SKIP = (1 << 4),
48
49 /* Features */
50 CS_CONFIG_MAP_JIT = (1 << 26),
51 CS_CONFIG_DEVELOPER_MODE_SUPPORTED = (1 << 27),
52 CS_CONFIG_COMPILATION_SERVICE = (1 << 28),
53 CS_CONFIG_LOCAL_SIGNING = (1 << 29),
54 CS_CONFIG_OOP_JIT = (1 << 30),
55 CS_CONFIG_CSM_ENABLED = (1 << 31),
56};
57
58#ifdef KERNEL_PRIVATE
59/* All definitions for XNU and kernel extensions */
60
61#include <mach/boolean.h>
62#include <mach/kern_return.h>
63#include <img4/firmware.h>
64
65#if !XNU_KERNEL_PRIVATE
66/*
67 * This header file is shared across the SDK and the KDK. When we're compiling code
68 * for the kernel, but not for XNU, such as a kernel extension, the code signing
69 * traps information is found through <image4/cs/traps.h>. When we're within XNU
70 * proper, this header shouldn't be directory included and instead we should include
71 * <libkern/image4/dlxk.h> instead, which is what we do within XNU_KERNEL_PRIVATE
72 * down below.
73 */
74#if __has_include(<image4/cs/traps.h>)
75#include <image4/cs/traps.h>
76#else
77typedef uint64_t image4_cs_trap_t;
78#endif /* __has_include(<image4/cs/traps.h>) */
79#endif /* !XNU_KERNEL_PRIVATE */
80
81/* Availability macros for KPI functions */
82#define XNU_SUPPORTS_CSM_TYPE 1
83#define XNU_SUPPORTS_CSM_APPLE_IMAGE4 1
84#define XNU_SUPPORTS_PROFILE_GARBAGE_COLLECTION 1
85#define XNU_SUPPORTS_COMPILATION_SERVICE 1
86#define XNU_SUPPORTS_LOCAL_SIGNING 1
87#define XNU_SUPPORTS_CE_ACCELERATION 1
88#define XNU_SUPPORTS_DISABLE_CODE_SIGNING_FEATURE 1
89#define XNU_SUPPORTS_IMAGE4_MONITOR_TRAP 1
90
91/* Local signing public key size */
92#define XNU_LOCAL_SIGNING_KEY_SIZE 97
93
94#if XNU_KERNEL_PRIVATE
95
96#include <sys/code_signing_internal.h>
97#include <libkern/img4/interface.h>
98#include <libkern/image4/dlxk.h>
99
100#if PMAP_CS_INCLUDE_CODE_SIGNING
101#if XNU_LOCAL_SIGNING_KEY_SIZE != PMAP_CS_LOCAL_SIGNING_KEY_SIZE
102#error "XNU local signing key size and PMAP_CS local signing key size differ!"
103#endif
104#endif /* PMAP_CS_INCLUDE_CODE_SIGNING */
105
106/* Common developer mode state variable */
107extern bool *developer_mode_enabled;
108
109/**
110 * This function is used to allocate code signing data which in some cases needs to
111 * align to a page length. This is a frequent operation, and as a result, a common
112 * helper is very useful.
113 */
114vm_address_t
115code_signing_allocate(
116 size_t alloc_size);
117
118/**
119 * This function is used to deallocate data received from code_signing_allocate.
120 */
121void
122code_signing_deallocate(
123 vm_address_t *alloc_addr,
124 size_t alloc_size);
125
126/**
127 * AppleImage4 does not provide an API to convert an object specification index to an
128 * actual object specification. Since this particular function is used across different
129 * places, it makes sense to keep it in a shared header file.
130 *
131 * This function may be called in contexts where printing is not possible, so do NOT
132 * leave a print statement here under any ciscumstances.
133 */
134static inline const img4_runtime_object_spec_t*
135image4_get_object_spec_from_index(
136 img4_runtime_object_spec_index_t obj_spec_index)
137{
138 const img4_runtime_object_spec_t *obj_spec = NULL;
139
140 switch (obj_spec_index) {
141 case IMG4_RUNTIME_OBJECT_SPEC_INDEX_SUPPLEMENTAL_ROOT:
142 obj_spec = IMG4_RUNTIME_OBJECT_SPEC_SUPPLEMENTAL_ROOT;
143 break;
144
145 case IMG4_RUNTIME_OBJECT_SPEC_INDEX_LOCAL_POLICY:
146 obj_spec = IMG4_RUNTIME_OBJECT_SPEC_LOCAL_POLICY;
147 break;
148
149 default:
150 break;
151 }
152
153 return obj_spec;
154}
155
156/**
157 * Perform any initialization required for managing code signing state on the system.
158 * This is called within XNU itself and doesn't need to be exported to anything external.
159 */
160void
161code_signing_init(void);
162
163#endif /* XNU_KERNEL_PRIVATE */
164
165/**
166 * Query the system to understand the code signing configuration of the system. This
167 * includes information on what monitor environment is available on the system as well
168 * as what the state of the system looks like with the provided boot-args.
169 */
170void
171code_signing_configuration(
172 code_signing_monitor_type_t *monitor_type,
173 code_signing_config_t *config);
174
175/**
176 * This function can be called by a component to disable a particular code signing
177 * feature on the system. For instance, code_signing_configuration is initialized in
178 * early boot, where some kernel extensions which affect code signing aren't online.
179 * When these extensions come online, they may choose to call this function to affect
180 * the state which was previously initialized within code_signing_configuration.
181 */
182void
183disable_code_signing_feature(
184 code_signing_config_t feature);
185
186/**
187 * Enable developer mode on the system. When the system contains a monitor environment,
188 * developer mode is turned on by trapping into the appropriate monitor environment.
189 */
190void
191enable_developer_mode(void);
192
193/**
194 * Disable developer mode on the system. When the system contains a monitor environment,
195 * developer mode is turned off by trapping into the appropriate monitor environment.
196 */
197void
198disable_developer_mode(void);
199
200/**
201 * Query the current state of developer mode on the system. This call never traps into
202 * the monitor environment because XNU can directly read the monitors memory.
203 */
204bool
205developer_mode_state(void);
206
207/**
208 * Wrapper function which is exposed to kernel extensions. This can be used to trigger
209 * a call to the garbage collector for going through and unregistring all unused profiles
210 * on the system.
211 */
212void
213garbage_collect_provisioning_profiles(void);
214
215/**
216 * Set the CDHash which is currently being used by the compilation service. This CDHash
217 * is compared against when validating the signature of a compilation service library.
218 */
219void
220set_compilation_service_cdhash(
221 const uint8_t *cdhash);
222
223/**
224 * Match a CDHash against the currently stored CDHash for the compilation service.
225 */
226bool
227match_compilation_service_cdhash(
228 const uint8_t *cdhash);
229
230/**
231 * Set the local signing key which is currently being used on the system. This key is used
232 * to validate any signatures which are signed on device.
233 */
234void
235set_local_signing_public_key(
236 const uint8_t public_key[XNU_LOCAL_SIGNING_KEY_SIZE]);
237
238/**
239 * Get the local signing key which is currently being used on the system. This API is
240 * mostly used by kernel extensions which validate code signatures on the platform.
241 */
242uint8_t*
243get_local_signing_public_key(void);
244
245/**
246 * Unrestrict a particular CDHash for local signing, allowing it to be loaded and run on
247 * the system. This is only required to be done for main binaries, since libraries do not
248 * need to be unrestricted.
249 */
250void
251unrestrict_local_signing_cdhash(
252 const uint8_t *cdhash);
253
254/**
255 * The kernel or the monitor environments allocate some data which is used by AppleImage4
256 * for storing critical system information such as nonces. AppleImage4 uses this API to
257 * get access to this data while abstracting the implementation underneath.
258 */
259void*
260kernel_image4_storage_data(
261 size_t *allocated_size);
262
263/**
264 * AppleImage4 uses this API to store the specified nonce into the nonce storage. This API
265 * abstracts away the kernel or monitor implementation used.
266 */
267void
268kernel_image4_set_nonce(
269 const img4_nonce_domain_index_t ndi,
270 const img4_nonce_t *nonce);
271
272/**
273 * AppleImage4 uses this API to roll a specified nonce on the next boot. This API abstracts
274 * away the kernel or monitor implementation used.
275 */
276void
277kernel_image4_roll_nonce(
278 const img4_nonce_domain_index_t ndi);
279
280/**
281 * AppleImage4 uses this API to copy a specified nonce from the nonce storage. This API
282 * abstracts away the kernel or monitor implementation used.
283 *
284 * We need this API since the nonces use a lock to protect against concurrency, and the
285 * lock can only be taken within the monitor environment, if any.
286 */
287errno_t
288kernel_image4_copy_nonce(
289 const img4_nonce_domain_index_t ndi,
290 img4_nonce_t *nonce_out);
291
292/**
293 * AppleImage4 uses this API to perform object execution on a particular object type. This
294 * API abstracts away the kernel or monitor implementation used.
295 */
296errno_t
297kernel_image4_execute_object(
298 img4_runtime_object_spec_index_t obj_spec_index,
299 const img4_buff_t *payload,
300 const img4_buff_t *manifest);
301
302/**
303 * AppleImage4 uses this API to copy the contents of an executed object. This API abstracts
304 * away the kernel or monitor implementation used.
305 */
306errno_t
307kernel_image4_copy_object(
308 img4_runtime_object_spec_index_t obj_spec_index,
309 vm_address_t object_out,
310 size_t *object_length);
311
312/**
313 * AppleImage4 uses this API to get a pointer to the structure which is used for exporting
314 * monitor locked down data to the rest of the system.
315 */
316const void*
317kernel_image4_get_monitor_exports(void);
318
319/**
320 * AppleImage4 uses this API to let the monitor environment know the release type for the
321 * the current boot. Under some circumstances, the monitor isn't able to gauge this on its
322 * own.
323 */
324errno_t
325kernel_image4_set_release_type(
326 const char *release_type);
327
328/**
329 * AppleImage4 uses this API to let the monitor know when a nonce domain is shadowing the
330 * AP boot nonce. Since this information is queried from the NVRAM, the monitor cant know
331 * this on its own.
332 */
333errno_t
334kernel_image4_set_bnch_shadow(
335 const img4_nonce_domain_index_t ndi);
336
337/**
338 * AppleImage4 uses this API to trap into the code signing monitor on the platform for
339 * the image4 dispatch routines. A single entry point is multiplexed into a whole dispatch
340 * table.
341 */
342errno_t
343kernel_image4_monitor_trap(
344 image4_cs_trap_t selector,
345 const void *input_data,
346 size_t input_size,
347 void *output_data,
348 size_t *output_size);
349
350/**
351 * AMFI uses this API to obtain the OSEntitlements object which is associated with the
352 * main binary mapped in for a process.
353 *
354 * This API is considered safer for resolving the OSEntitlements than through the cred
355 * structure on the process because the system maintains a strong binding in the linkage
356 * chain from the process structure through the pmap, which ultimately contains the
357 * code signing monitors address space information for the process.
358 */
359kern_return_t
360csm_resolve_os_entitlements_from_proc(
361 const proc_t process,
362 const void **os_entitlements);
363
364/**
365 * Wrapper function that calls csm_get_trust_level_kdp if there is a CODE_SIGNING_MONITOR
366 * or returns KERN_NOT_SUPPORTED if there isn't one.
367 */
368kern_return_t
369get_trust_level_kdp(
370 pmap_t pmap,
371 uint32_t *trust_level);
372
373/**
374 * Check whether a particular proc is marked as debugged or not. For many use cases, this
375 * is a stronger check than simply checking for the enablement of developer mode since
376 * an address space can only be marked as debugged if developer mode is already enabled.
377 *
378 * When the system has a code signing monitor, this function acquires the state of the
379 * address space from the monitor.
380 */
381kern_return_t
382address_space_debugged(
383 const proc_t process);
384
385#if CODE_SIGNING_MONITOR
386
387/**
388 * Check to see if the monitor is currently enforcing code signing protections or
389 * not. Even when this is disabled, certains artifacts are still protected by the
390 * monitor environment.
391 */
392bool
393csm_enabled(void);
394
395/**
396 * Check and inform the code signing monitor that the system is entering lockdown mode.
397 * The code signing monitor then enforces policy based on this state. As part of this,
398 * we also update the code signing configuration of the system.
399 */
400void
401csm_check_lockdown_mode(void);
402
403/**
404 * When a task incurs an unresolvable page fault with execute permissions, and is not
405 * being debugged, the task should receive a SIGKILL. This should only happen if the
406 * task isn't actively being debugged. This function abstracts all these details.
407 */
408void
409csm_code_signing_violation(
410 proc_t proc,
411 vm_offset_t addr);
412
413/**
414 * This function is used to initialize the state of the locks for managing provisioning
415 * profiles on the system. It should be called by the kernel bootstrap thread during the
416 * early kernel initialization.
417 */
418void
419csm_initialize_provisioning_profiles(void);
420
421/**
422 * Register a provisioning profile with the monitor environment available on the
423 * system. This function will allocate its own memory for managing the profile and
424 * the caller is allowed to free their own allocation.
425 */
426kern_return_t
427csm_register_provisioning_profile(
428 const uuid_t profile_uuid,
429 const void *profile,
430 const size_t profile_size);
431
432/**
433 * Associate a registered profile with a code signature object which is managed by
434 * the monitor environment. This incrementes the reference count on the profile object
435 * managed by the monitor, preventing the profile from being unregistered.
436 */
437kern_return_t
438csm_associate_provisioning_profile(
439 void *monitor_sig_obj,
440 const uuid_t profile_uuid);
441
442/**
443 * Disassociate an associated profile with a code signature object which is managed by
444 * the monitor environment. This decrements the refernce count on the profile object
445 * managed by the monitor, potentially allowing it to be unregistered in case no other
446 * signatures hold a reference count to it.
447 */
448kern_return_t
449csm_disassociate_provisioning_profile(
450 void *monitor_sig_obj);
451
452/**
453 * Trigger the provisioning profile garbage collector to go through each registered
454 * profile on the system and unregister it in case it isn't being used.
455 */
456void
457csm_free_provisioning_profiles(void);
458
459/**
460 * Acquire the largest size for a code signature which the monitor will allocate on
461 * its own. Anything larger than this size needs to be page-allocated and aligned and
462 * will be locked down by the monitor upon registration.
463 */
464vm_size_t
465csm_signature_size_limit(void);
466
467/**
468 * Register a code signature with the monitor environment. The monitor will either
469 * allocate its own memory for the code signature, or it will lockdown the memory which
470 * is given to it. In either case, the signature will be read-only for the kernel.
471 *
472 * If the monitor doesn't enforce code signing, then this function will return the
473 * KERN_SUCCESS condition.
474 */
475kern_return_t
476csm_register_code_signature(
477 const vm_address_t signature_addr,
478 const vm_size_t signature_size,
479 const vm_offset_t code_directory_offset,
480 const char *signature_path,
481 void **monitor_sig_obj,
482 vm_address_t *monitor_signature_addr);
483
484/**
485 * Unregister a code signature previously registered with the monitor environment.
486 * This will free (or unlock) the signature memory held by the monitor.
487 *
488 * If the monitor doesn't enforce code signing, then this function will return the
489 * error KERN_NOT_SUPPORTED.
490 */
491kern_return_t
492csm_unregister_code_signature(
493 void *monitor_sig_obj);
494
495/**
496 * Verify a code signature previously registered with the monitor. After verification,
497 * the signature can be used for making code signature associations with address spaces.
498 *
499 * If the monitor doesn't enforce code signing, then this function will return the
500 * KERN_SUCCESS condition.
501 */
502kern_return_t
503csm_verify_code_signature(
504 void *monitor_sig_obj);
505
506/**
507 * Perform 2nd stage reconstitution through the monitor. This unlocks any unused parts
508 * of the code signature, which can then be freed by the kernel. This isn't strictly
509 * required, but it helps in conserving system memory.
510 *
511 * If the monitor doesn't enforce code signing, then this function will return the
512 * error KERN_NOT_SUPPORTED.
513 */
514kern_return_t
515csm_reconstitute_code_signature(
516 void *monitor_sig_obj,
517 vm_address_t *unneeded_addr,
518 vm_size_t *unneeded_size);
519
520/**
521 * Associate a code signature with an address space for a specified region with the
522 * monitor environment. The code signature can only be associated if it has been
523 * verified before.
524 */
525kern_return_t
526csm_associate_code_signature(
527 pmap_t pmap,
528 void *monitor_sig_obj,
529 const vm_address_t region_addr,
530 const vm_size_t region_size,
531 const vm_offset_t region_offset);
532
533/**
534 * Validate that an address space will allow mapping in a JIT region within the monitor
535 * environment. An address space can only have a single JIT region, and only when it
536 * has the appropriate JIT entitlement.
537 */
538kern_return_t
539csm_allow_jit_region(
540 pmap_t pmap);
541
542/**
543 * Associate a JIT region with an address space in the monitor environment. An address
544 * space can only have a JIT region if it has the appropriate JIT entitlement.
545 */
546kern_return_t
547csm_associate_jit_region(
548 pmap_t pmap,
549 const vm_address_t region_addr,
550 const vm_size_t region_size);
551
552/**
553 * Associate a debug region with an address space in the monitor environment. An address
554 * space can only have a debug region if it is currently being debugged.
555 */
556kern_return_t
557csm_associate_debug_region(
558 pmap_t pmap,
559 const vm_address_t region_addr,
560 const vm_size_t region_size);
561
562/**
563 * Call out to the monitor to inform it that the address space needs to be debugged. The
564 * monitor will only allow the address space to be debugged if it has the appropriate
565 * entitlements.
566 */
567kern_return_t
568csm_allow_invalid_code(
569 pmap_t pmap);
570
571/**
572 * Acquire the trust level which is placed on the address space within the monitor
573 * environment. There is no clear mapping of the 32-bit integer returned to the actual
574 * trust level because different code signing monitors use different trust levels.
575 *
576 * The code signing monitor itself does not depend on this value and instead uses
577 * other, more secure methods of checking for trust. In general, we only expect this
578 * function to be used for debugging purposes.
579 *
580 * This function should be careful that any code paths within it do not mutate the
581 * state of the system, and as a result, no code paths here should attempt to take
582 * locks of any kind.
583 */
584kern_return_t
585csm_get_trust_level_kdp(
586 pmap_t pmap,
587 uint32_t *trust_level);
588
589/**
590 * Certain address spaces are exempt from code signing enforcement. This function can be
591 * used to check if the specified address space is such or not.
592 */
593kern_return_t
594csm_address_space_exempt(
595 const pmap_t pmap);
596
597/**
598 * Instruct the monitor that an address space is about to be forked. The monitor can then
599 * do whatever it needs to do in order to prepare for the fork.
600 */
601kern_return_t
602csm_fork_prepare(
603 pmap_t old_pmap,
604 pmap_t new_pmap);
605
606/**
607 * Get the signing identifier which is embedded within the code directory using the
608 * code signing monitor's abstract signature object.
609 */
610kern_return_t
611csm_acquire_signing_identifier(
612 const void *monitor_sig_obj,
613 const char **signing_id);
614
615/**
616 * This API to associate an OSEntitlements objects with the code signing monitor's
617 * signature object. This binding is useful as it can be used to resolve the entitlement
618 * object which is used by the kernel for performing queries.
619 */
620kern_return_t
621csm_associate_os_entitlements(
622 void *monitor_sig_obj,
623 const void *os_entitlements);
624
625/**
626 * Accelerate the CoreEntitlements context within the code signing monitor's memory
627 * in order to speed up all queries for entitlements going through CoreEntitlements.
628 */
629kern_return_t
630csm_accelerate_entitlements(
631 void *monitor_sig_obj,
632 CEQueryContext_t *ce_ctx);
633
634kern_return_t
635vm_map_entry_cs_associate(
636 vm_map_t map,
637 struct vm_map_entry *entry,
638 vm_map_kernel_flags_t vmk_flags);
639
640kern_return_t
641cs_associate_blob_with_mapping(
642 void *pmap,
643 vm_map_offset_t start,
644 vm_map_size_t size,
645 vm_object_offset_t offset,
646 void *blobs_p);
647
648#endif /* CODE_SIGNING_MONITOR */
649
650#endif /* KERNEL_PRIVATE */
651
652#pragma GCC diagnostic pop
653
654__END_DECLS
655#endif /* _SYS_CODE_SIGNING_H_ */
656