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