]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/i386/IOKeyStoreHelper.cpp
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / iokit / Kernel / i386 / IOKeyStoreHelper.cpp
1 /*
2 * Copyright (c) 2010 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 #include <sys/cdefs.h>
30 #include <stdbool.h>
31
32 #include <IOKit/assert.h>
33 #include <IOKit/system.h>
34 #include <IOKit/IOLib.h>
35 #include <IOKit/IOMemoryDescriptor.h>
36 #include <IOKit/IOKitDebug.h>
37
38 __BEGIN_DECLS
39
40 #include <pexpert/pexpert.h>
41
42 static volatile UInt32 alreadyFetched = 0;
43 static IOMemoryDescriptor * newData;
44
45 IOMemoryDescriptor *
46 IOGetBootKeyStoreData(void);
47 void
48 IOSetKeyStoreData(IOMemoryDescriptor * data);
49
50 // APFS
51 static volatile UInt32 apfsKeyFetched = 0;
52 static IOMemoryDescriptor* apfsKeyData = NULL;
53
54 IOMemoryDescriptor* IOGetAPFSKeyStoreData();
55 void IOSetAPFSKeyStoreData(IOMemoryDescriptor* data);
56
57 static volatile UInt32 arvRootHashFetched = 0;
58 static volatile UInt32 bsARVRootHashFetched = 0;
59 static IOMemoryDescriptor* arvRootHashData = NULL;
60 static IOMemoryDescriptor* bsARVRootHashData = NULL;
61
62 IOMemoryDescriptor* IOGetARVRootHashData(void);
63 void IOSetARVRootHashData(IOMemoryDescriptor* arvData);
64
65 IOMemoryDescriptor* IOGetBaseSystemARVRootHashData(void);
66 bool IOBaseSystemARVRootHashAvailable(void);
67 void IOSetBaseSystemARVRootHashData(IOMemoryDescriptor* arvData);
68
69
70 static volatile UInt32 arvManifestFetched = 0;
71 static IOMemoryDescriptor* arvManifestData = NULL;
72
73 IOMemoryDescriptor* IOGetARVManifestData(void);
74 void IOSetARVManifestData(IOMemoryDescriptor* arvData);
75
76 __END_DECLS
77
78 #if 1
79 #define DEBG(fmt, args...) { kprintf(fmt, ## args); }
80 #else
81 #define DEBG(fmt, args...) {}
82 #endif
83
84 void
85 IOSetKeyStoreData(IOMemoryDescriptor * data)
86 {
87 newData = data;
88 alreadyFetched = 0;
89 }
90
91 IOMemoryDescriptor *
92 IOGetBootKeyStoreData(void)
93 {
94 IOMemoryDescriptor *memoryDescriptor;
95 boot_args *args = (boot_args *)PE_state.bootArgs;
96 IOOptionBits options;
97 IOAddressRange ranges;
98
99 if (!OSCompareAndSwap(0, 1, &alreadyFetched)) {
100 return NULL;
101 }
102
103 if (newData) {
104 IOMemoryDescriptor * data = newData;
105 newData = NULL;
106 return data;
107 }
108
109 DEBG("%s: data at address %u size %u\n", __func__,
110 args->keyStoreDataStart,
111 args->keyStoreDataSize);
112
113 if (args->keyStoreDataStart == 0) {
114 return NULL;
115 }
116
117 ranges.address = args->keyStoreDataStart;
118 ranges.length = args->keyStoreDataSize;
119
120 options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
121
122 memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges,
123 1,
124 0,
125 NULL,
126 options);
127
128 DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
129
130 return memoryDescriptor;
131 }
132
133 // APFS volume key fetcher
134
135 // Store in-memory key (could be used by IOHibernateDone)
136 void
137 IOSetAPFSKeyStoreData(IOMemoryDescriptor* data)
138 {
139 // Do not allow re-fetching of the boot_args key by passing NULL here.
140 if (data != NULL) {
141 apfsKeyData = data;
142 apfsKeyFetched = 0;
143 }
144 }
145
146 // Retrieve any key we may have (stored in boot_args or by Hibernate)
147 IOMemoryDescriptor*
148 IOGetAPFSKeyStoreData()
149 {
150 // Check if someone got the key before us
151 if (!OSCompareAndSwap(0, 1, &apfsKeyFetched)) {
152 return NULL;
153 }
154
155 // Do we have in-memory key?
156 if (apfsKeyData) {
157 IOMemoryDescriptor* data = apfsKeyData;
158 apfsKeyData = NULL;
159 return data;
160 }
161
162 // Looks like there was no in-memory key and it's the first call - try boot_args
163 boot_args* args = (boot_args*)PE_state.bootArgs;
164
165 DEBG("%s: data at address %u size %u\n", __func__, args->apfsDataStart, args->apfsDataSize);
166 if (args->apfsDataStart == 0) {
167 return NULL;
168 }
169
170 // We have the key in the boot_args, create IOMemoryDescriptor for the blob
171 IOAddressRange ranges;
172 ranges.address = args->apfsDataStart;
173 ranges.length = args->apfsDataSize;
174
175 const IOOptionBits options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
176
177 IOMemoryDescriptor* memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges, 1, 0, NULL, options);
178 DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
179 return memoryDescriptor;
180 }
181
182 // ARV Root Hash fetcher
183
184 // Store in-memory Root Hash
185 void
186 IOSetARVRootHashData(IOMemoryDescriptor* arvData)
187 {
188 // Do not allow re-fetching of the boot_args root hash by passing NULL here.
189 if (arvData) {
190 arvRootHashData = arvData;
191 arvRootHashFetched = 0;
192 }
193 }
194
195 // Retrieve any root hash we may have (stored in boot_args or in-memory)
196 IOMemoryDescriptor*
197 IOGetARVRootHashData(void)
198 {
199 // Check if someone got the root hash before us
200 if (!OSCompareAndSwap(0, 1, &arvRootHashFetched)) {
201 return NULL;
202 }
203
204 // Do we have in-memory root hash?
205 if (arvRootHashData) {
206 IOMemoryDescriptor* arvData = arvRootHashData;
207 arvRootHashData = NULL;
208 return arvData;
209 }
210
211 // Looks like there was no in-memory root hash and it's the first call - try boot_args
212 boot_args* args = (boot_args*)PE_state.bootArgs;
213
214 DEBG("%s: data at address %llu size %llu\n", __func__, args->arvRootHashStart, args->arvRootHashSize);
215 if (args->arvRootHashStart == 0) {
216 return NULL;
217 }
218
219 // We have the root hash in the boot_args, create IOMemoryDescriptor for the blob
220 IOAddressRange ranges;
221 ranges.address = args->arvRootHashStart;
222 ranges.length = args->arvRootHashSize;
223
224 const IOOptionBits options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
225
226 IOMemoryDescriptor* memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges, 1, 0, NULL, options);
227 DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
228 return memoryDescriptor;
229 }
230
231 // Base System Analogues
232
233 IOMemoryDescriptor*
234 IOGetBaseSystemARVRootHashData(void)
235 {
236 //TBD!
237 return NULL;
238 }
239
240 bool
241 IOBaseSystemARVRootHashAvailable(void)
242 {
243 // Check if someone got the root hash before us
244 if (!OSCompareAndSwap(0, 1, &bsARVRootHashFetched)) {
245 return false;
246 }
247
248 // Do we have in-memory root hash?
249 if (bsARVRootHashData) {
250 return true;
251 }
252 return false;
253 }
254
255
256 void
257 IOSetBaseSystemARVRootHashData(IOMemoryDescriptor* arvData)
258 {
259 return;
260 }
261
262
263 // ARV Manifest fetcher
264
265 // Store in-memory Manifest
266 void
267 IOSetARVManifestData(IOMemoryDescriptor* arvData)
268 {
269 // Do not allow re-fetching of the boot_args manifest by passing NULL here.
270 if (arvData) {
271 arvManifestData = arvData;
272 arvManifestFetched = 0;
273 }
274 }
275
276 // Retrieve any manifest we may have (stored in boot_args or in-memory)
277 IOMemoryDescriptor*
278 IOGetARVManifestData(void)
279 {
280 // Check if someone got the manifest before us
281 if (!OSCompareAndSwap(0, 1, &arvManifestFetched)) {
282 return NULL;
283 }
284
285 // Do we have in-memory manifest?
286 if (arvManifestData) {
287 IOMemoryDescriptor* arvData = arvManifestData;
288 arvManifestData = NULL;
289 return arvData;
290 }
291
292 // Looks like there was no in-memory manifest and it's the first call - try boot_args
293 boot_args* args = (boot_args*)PE_state.bootArgs;
294
295 DEBG("%s: data at address %llu size %llu\n", __func__, args->arvManifestStart, args->arvManifestSize);
296 if (args->arvManifestStart == 0) {
297 return NULL;
298 }
299
300 // We have the manifest in the boot_args, create IOMemoryDescriptor for the blob
301 IOAddressRange ranges;
302 ranges.address = args->arvManifestStart;
303 ranges.length = args->arvManifestSize;
304
305 const IOOptionBits options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
306
307 IOMemoryDescriptor* memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges, 1, 0, NULL, options);
308 DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
309 return memoryDescriptor;
310 }