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