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 }
311