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 80 IOSetKeyStoreData(IOMemoryDescriptor * data) 81 { 82 newData = data; 83 alreadyFetched = 0; 84 } 85 86 IOMemoryDescriptor * 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 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* 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* 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* 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 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* 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* 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