xref: /xnu-11417.140.69/EXTERNAL_HEADERS/corecrypto/cc_lock.h (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1 /* Copyright (c) (2021-2023) Apple Inc. All rights reserved.
2  *
3  * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4  * is contained in the License.txt file distributed with corecrypto) and only to
5  * people who accept that license. IMPORTANT:  Any license rights granted to you by
6  * Apple Inc. (if any) are limited to internal use within your organization only on
7  * devices and computers you own or control, for the sole purpose of verifying the
8  * security characteristics and correct functioning of the Apple Software.  You may
9  * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
10  */
11 
12 #ifndef _CORECRYPTO_CC_LOCK_H_
13 #define _CORECRYPTO_CC_LOCK_H_
14 
15 #include <corecrypto/cc_priv.h>
16 
17 typedef struct cc_lock_ctx cc_lock_ctx_t;
18 int cc_lock_init(cc_lock_ctx_t *ctx, const char *group_name);
19 
20 #if defined(_WIN32)
21 #include <windows.h>
22 #endif
23 
24 //==============================================================================
25 //
26 //          corecrypto support for multithreaded environments
27 //
28 // This part of corecrypto is OS dependent and it serves two purposes
29 // a) It allows multiple threads to use ccrng()
30 // b) If the process is forked, it reseeds the ccrng, so that parent and child
31 //    state differs and generate different random numbers
32 //==============================================================================
33 
34 #if CC_USE_L4 || CC_USE_SEPROM || CC_RTKIT || CC_RTKITROM
35 #define CC_LOCK_IMPL_NULL 1
36 #define CC_LOCK_IMPL_POSIX 0
37 #define CC_LOCK_IMPL_USER 0
38 #define CC_LOCK_IMPL_WIN 0
39 #define CC_LOCK_IMPL_KERNEL 0
40 #define CC_LOCK_IMPL_SGX 0
41 #elif CC_LINUX && CC_KERNEL && CC_DARWIN && CORECRYPTO_SIMULATE_POSIX_ENVIRONMENT
42 // this is only to allow linux development on macOS. It is not useful in practice.
43 #define CC_LOCK_IMPL_NULL 0
44 #define CC_LOCK_IMPL_POSIX 0
45 #define CC_LOCK_IMPL_USER 0
46 #define CC_LOCK_IMPL_WIN 0
47 #define CC_LOCK_IMPL_KERNEL 1
48 #define CC_LOCK_IMPL_SGX 0
49 #elif CC_DARWIN && !CC_KERNEL && !CC_EFI && CC_INTERNAL_SDK
50 // For Apple OSs (macOS, iOS, watchOS, tvOS), except kernel, L4 and EFI
51 #define CC_LOCK_IMPL_NULL 0
52 #define CC_LOCK_IMPL_POSIX 0
53 #define CC_LOCK_IMPL_USER 1
54 #define CC_LOCK_IMPL_WIN 0
55 #define CC_LOCK_IMPL_KERNEL 0
56 #define CC_LOCK_IMPL_SGX 0
57 #elif CC_DARWIN && CC_KERNEL // For the Apple Kernel
58 #define CC_LOCK_IMPL_NULL 0
59 #define CC_LOCK_IMPL_POSIX 0
60 #define CC_LOCK_IMPL_USER 0
61 #define CC_LOCK_IMPL_WIN 0
62 #define CC_LOCK_IMPL_KERNEL 1
63 #define CC_LOCK_IMPL_SGX 0
64 #elif defined(_WIN32) // for Windows
65 #define CC_LOCK_IMPL_NULL 0
66 #define CC_LOCK_IMPL_POSIX 0
67 #define CC_LOCK_IMPL_USER 0
68 #define CC_LOCK_IMPL_WIN 1
69 #define CC_LOCK_IMPL_KERNEL 0
70 #define CC_LOCK_IMPL_SGX 0
71 #elif CC_SGX // for SGX Enclave
72 #define CC_LOCK_IMPL_NULL 0
73 #define CC_LOCK_IMPL_POSIX 0
74 #define CC_LOCK_IMPL_USER 0
75 #define CC_LOCK_IMPL_WIN 0
76 #define CC_LOCK_IMPL_KERNEL 0
77 #define CC_LOCK_IMPL_SGX 1
78 #elif CC_LINUX || !CC_INTERNAL_SDK // for systems that support pthread, such as Linux
79 #define CC_LOCK_IMPL_NULL 0
80 #define CC_LOCK_IMPL_POSIX 1
81 #define CC_LOCK_IMPL_USER 0
82 #define CC_LOCK_IMPL_WIN 0
83 #define CC_LOCK_IMPL_KERNEL 0
84 #define CC_LOCK_IMPL_SGX 0
85 #else
86 #error No multithread environment defined for cc_lock.
87 #endif
88 
89 #if CC_LOCK_IMPL_NULL
90 
91 #define CC_LOCK_LOCK(lock_ctx) cc_try_abort("CC_LOCK_LOCK not implemented")
92 #define CC_LOCK_TRYLOCK(lock_ctx) cc_try_abort("CC_LOCK_TRYLOCK not implemented")
93 #define CC_LOCK_UNLOCK(lock_ctx) cc_try_abort("CC_LOCK_UNLOCK not implemented")
94 #define CC_LOCK_ASSERT(lock_ctx) cc_try_abort("CC_LOCK_ASSERT not implemented")
95 
96 struct cc_lock_ctx {
97 };
98 
99 //------------------------------------------------------------------------------
100 // os/lock library, Apple userland
101 //------------------------------------------------------------------------------
102 #elif CC_LOCK_IMPL_USER
103 #include <pthread.h>
104 #include <os/lock.h>
105 
106 #define CC_LOCK_LOCK(lock_ctx) os_unfair_lock_lock(&(lock_ctx)->lock)
107 #define CC_LOCK_TRYLOCK(lock_ctx) os_unfair_lock_trylock(&(lock_ctx)->lock)
108 #define CC_LOCK_UNLOCK(lock_ctx) os_unfair_lock_unlock(&(lock_ctx)->lock)
109 #define CC_LOCK_ASSERT(lock_ctx) os_unfair_lock_assert_owner(&(lock_ctx)->lock)
110 
111 struct cc_lock_ctx {
112     os_unfair_lock lock;
113 };
114 
115 //------------------------------------------------------------------------------
116 //          POSIX library, Linux
117 //------------------------------------------------------------------------------
118 #elif CC_LOCK_IMPL_POSIX
119 #include <pthread.h>
120 
121 #define CC_LOCK_LOCK(lock_ctx) (pthread_mutex_lock(&(lock_ctx)->mutex) == 0)
122 #define CC_LOCK_TRYLOCK(lock_ctx) (pthread_mutex_trylock(&(lock_ctx)->mutex) == 0)
123 #define CC_LOCK_UNLOCK(lock_ctx) (pthread_mutex_unlock(&(lock_ctx)->mutex) == 0)
124 #define CC_LOCK_ASSERT(lock_ctx) do { } while (0)
125 
126 struct cc_lock_ctx {
127     pthread_mutex_t mutex;
128 };
129 
130 //------------------------------------------------------------------------------
131 //          Kext, XNU
132 //------------------------------------------------------------------------------
133 #elif CC_LOCK_IMPL_KERNEL
134 
135 #include <kern/locks.h>
136 #define CC_LOCK_LOCK(lock_ctx) lck_mtx_lock((lock_ctx)->mutex)
137 #define CC_LOCK_TRYLOCK(lock_ctx) lck_mtx_try_lock((lock_ctx)->mutex)
138 #define CC_LOCK_UNLOCK(lock_ctx) lck_mtx_unlock((lock_ctx)->mutex)
139 #define CC_LOCK_ASSERT(lock_ctx) lck_mtx_assert((lock_ctx)->mutex, LCK_MTX_ASSERT_OWNED);
140 
141 struct cc_lock_ctx {
142     lck_mtx_t *mutex;
143     lck_grp_t *group;
144 };
145 
146 //------------------------------------------------------------------------------
147 //          Windows
148 //------------------------------------------------------------------------------
149 #elif CC_LOCK_IMPL_WIN
150 
151 #define CC_LOCK_LOCK(lock_ctx)                                          \
152     if (WaitForSingleObject((lock_ctx)->hMutex, INFINITE) != WAIT_OBJECT_0) \
153         return CCERR_INTERNAL;
154 #define CC_LOCK_UNLOCK(lock_ctx) ReleaseMutex((lock_ctx)->hMutex)
155 #define CC_LOCK_ASSERT(lock_ctx) do { } while (0)
156 
157 struct cc_lock_ctx {
158     HANDLE hMutex;
159 };
160 
161 //------------------------------------------------------------------------------
162 //          SGX
163 //------------------------------------------------------------------------------
164 #elif CC_LOCK_IMPL_SGX
165 // Avoid an OCALL in the middle of RNG routines: use spinlocks instead of mutexes.
166 #include <pthread.h>
167 
168 #define CC_LOCK_LOCK(lock_ctx)   pthread_spin_lock(&(lock_ctx)->lock)
169 #define CC_LOCK_UNLOCK(lock_ctx) pthread_spin_unlock(&(lock_ctx)->lock)
170 #define CC_LOCK_ASSERT(lock_ctx) do { } while (0)
171 
172 struct cc_lock_ctx {
173     pthread_spinlock_t lock;
174 };
175 
176 //------------------------------------------------------------------------------
177 //          default
178 //------------------------------------------------------------------------------
179 #else
180 #error "cc_lock is not implemented."
181 #endif /* CC_LOCK_IMPL_USER */
182 
183 #endif /* _CORECRYPTO_CC_LOCK_H_ */
184