2 * Copyright (c) 2010 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/cdefs.h>
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>
40 #include <pexpert/pexpert.h>
42 static volatile UInt32 alreadyFetched
= 0;
43 static IOMemoryDescriptor
* newData
;
46 IOGetBootKeyStoreData(void);
48 IOSetKeyStoreData(IOMemoryDescriptor
* data
);
51 static volatile UInt32 apfsKeyFetched
= 0;
52 static IOMemoryDescriptor
* apfsKeyData
= NULL
;
54 IOMemoryDescriptor
* IOGetAPFSKeyStoreData();
55 void IOSetAPFSKeyStoreData(IOMemoryDescriptor
* data
);
57 static volatile UInt32 arvRootHashFetched
= 0;
58 static volatile UInt32 bsARVRootHashFetched
= 0;
59 static IOMemoryDescriptor
* arvRootHashData
= NULL
;
60 static IOMemoryDescriptor
* bsARVRootHashData
= NULL
;
62 IOMemoryDescriptor
* IOGetARVRootHashData(void);
63 void IOSetARVRootHashData(IOMemoryDescriptor
* arvData
);
65 IOMemoryDescriptor
* IOGetBaseSystemARVRootHashData(void);
66 bool IOBaseSystemARVRootHashAvailable(void);
67 void IOSetBaseSystemARVRootHashData(IOMemoryDescriptor
* arvData
);
70 static volatile UInt32 arvManifestFetched
= 0;
71 static IOMemoryDescriptor
* arvManifestData
= NULL
;
73 IOMemoryDescriptor
* IOGetARVManifestData(void);
74 void IOSetARVManifestData(IOMemoryDescriptor
* arvData
);
79 #define DEBG(fmt, args...) { kprintf(fmt, ## args); }
81 #define DEBG(fmt, args...) {}
85 IOSetKeyStoreData(IOMemoryDescriptor
* data
)
92 IOGetBootKeyStoreData(void)
94 IOMemoryDescriptor
*memoryDescriptor
;
95 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
97 IOAddressRange ranges
;
99 if (!OSCompareAndSwap(0, 1, &alreadyFetched
)) {
104 IOMemoryDescriptor
* data
= newData
;
109 DEBG("%s: data at address %u size %u\n", __func__
,
110 args
->keyStoreDataStart
,
111 args
->keyStoreDataSize
);
113 if (args
->keyStoreDataStart
== 0) {
117 ranges
.address
= args
->keyStoreDataStart
;
118 ranges
.length
= args
->keyStoreDataSize
;
120 options
= kIODirectionInOut
| kIOMemoryTypePhysical64
| kIOMemoryMapperNone
;
122 memoryDescriptor
= IOMemoryDescriptor::withOptions(&ranges
,
128 DEBG("%s: memory descriptor %p\n", __func__
, memoryDescriptor
);
130 return memoryDescriptor
;
133 // APFS volume key fetcher
135 // Store in-memory key (could be used by IOHibernateDone)
137 IOSetAPFSKeyStoreData(IOMemoryDescriptor
* data
)
139 // Do not allow re-fetching of the boot_args key by passing NULL here.
146 // Retrieve any key we may have (stored in boot_args or by Hibernate)
148 IOGetAPFSKeyStoreData()
150 // Check if someone got the key before us
151 if (!OSCompareAndSwap(0, 1, &apfsKeyFetched
)) {
155 // Do we have in-memory key?
157 IOMemoryDescriptor
* data
= apfsKeyData
;
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
;
165 DEBG("%s: data at address %u size %u\n", __func__
, args
->apfsDataStart
, args
->apfsDataSize
);
166 if (args
->apfsDataStart
== 0) {
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
;
175 const IOOptionBits options
= kIODirectionInOut
| kIOMemoryTypePhysical64
| kIOMemoryMapperNone
;
177 IOMemoryDescriptor
* memoryDescriptor
= IOMemoryDescriptor::withOptions(&ranges
, 1, 0, NULL
, options
);
178 DEBG("%s: memory descriptor %p\n", __func__
, memoryDescriptor
);
179 return memoryDescriptor
;
182 // ARV Root Hash fetcher
184 // Store in-memory Root Hash
186 IOSetARVRootHashData(IOMemoryDescriptor
* arvData
)
188 // Do not allow re-fetching of the boot_args root hash by passing NULL here.
190 arvRootHashData
= arvData
;
191 arvRootHashFetched
= 0;
195 // Retrieve any root hash we may have (stored in boot_args or in-memory)
197 IOGetARVRootHashData(void)
199 // Check if someone got the root hash before us
200 if (!OSCompareAndSwap(0, 1, &arvRootHashFetched
)) {
204 // Do we have in-memory root hash?
205 if (arvRootHashData
) {
206 IOMemoryDescriptor
* arvData
= arvRootHashData
;
207 arvRootHashData
= NULL
;
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
;
214 DEBG("%s: data at address %llu size %llu\n", __func__
, args
->arvRootHashStart
, args
->arvRootHashSize
);
215 if (args
->arvRootHashStart
== 0) {
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
;
224 const IOOptionBits options
= kIODirectionInOut
| kIOMemoryTypePhysical64
| kIOMemoryMapperNone
;
226 IOMemoryDescriptor
* memoryDescriptor
= IOMemoryDescriptor::withOptions(&ranges
, 1, 0, NULL
, options
);
227 DEBG("%s: memory descriptor %p\n", __func__
, memoryDescriptor
);
228 return memoryDescriptor
;
231 // Base System Analogues
234 IOGetBaseSystemARVRootHashData(void)
241 IOBaseSystemARVRootHashAvailable(void)
243 // Check if someone got the root hash before us
244 if (!OSCompareAndSwap(0, 1, &bsARVRootHashFetched
)) {
248 // Do we have in-memory root hash?
249 if (bsARVRootHashData
) {
257 IOSetBaseSystemARVRootHashData(IOMemoryDescriptor
* arvData
)
263 // ARV Manifest fetcher
265 // Store in-memory Manifest
267 IOSetARVManifestData(IOMemoryDescriptor
* arvData
)
269 // Do not allow re-fetching of the boot_args manifest by passing NULL here.
271 arvManifestData
= arvData
;
272 arvManifestFetched
= 0;
276 // Retrieve any manifest we may have (stored in boot_args or in-memory)
278 IOGetARVManifestData(void)
280 // Check if someone got the manifest before us
281 if (!OSCompareAndSwap(0, 1, &arvManifestFetched
)) {
285 // Do we have in-memory manifest?
286 if (arvManifestData
) {
287 IOMemoryDescriptor
* arvData
= arvManifestData
;
288 arvManifestData
= NULL
;
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
;
295 DEBG("%s: data at address %llu size %llu\n", __func__
, args
->arvManifestStart
, args
->arvManifestSize
);
296 if (args
->arvManifestStart
== 0) {
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
;
305 const IOOptionBits options
= kIODirectionInOut
| kIOMemoryTypePhysical64
| kIOMemoryMapperNone
;
307 IOMemoryDescriptor
* memoryDescriptor
= IOMemoryDescriptor::withOptions(&ranges
, 1, 0, NULL
, options
);
308 DEBG("%s: memory descriptor %p\n", __func__
, memoryDescriptor
);
309 return memoryDescriptor
;