]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/i386/IOKeyStoreHelper.cpp
xnu-6153.121.1.tar.gz
[apple/xnu.git] / iokit / Kernel / i386 / IOKeyStoreHelper.cpp
index a1d41b8d0a1773a7c9f6e0fde8d3e4a07159db1c..88b077a25314d68b74ff37c485df870503fcc04f 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
@@ -47,58 +47,115 @@ IOGetBootKeyStoreData(void);
 void
 IOSetKeyStoreData(IOMemoryDescriptor * data);
 
+// APFS
+static volatile UInt32 apfsKeyFetched = 0;
+static IOMemoryDescriptor* apfsKeyData = NULL;
+
+IOMemoryDescriptor* IOGetAPFSKeyStoreData();
+void IOSetAPFSKeyStoreData(IOMemoryDescriptor* data);
+
 __END_DECLS
 
 #if 1
-#define DEBG(fmt, args...)     { kprintf(fmt, ## args); }
+#define DEBG(fmt, args...)      { kprintf(fmt, ## args); }
 #else
-#define DEBG(fmt, args...)     {}
+#define DEBG(fmt, args...)      {}
 #endif
 
 void
 IOSetKeyStoreData(IOMemoryDescriptor * data)
 {
-    newData = data;
-    alreadyFetched = 0;
+       newData = data;
+       alreadyFetched = 0;
 }
 
 IOMemoryDescriptor *
 IOGetBootKeyStoreData(void)
 {
-  IOMemoryDescriptor *memoryDescriptor;
-  boot_args *args = (boot_args *)PE_state.bootArgs;
-  IOOptionBits options;
-  IOAddressRange ranges;
-
-  if (!OSCompareAndSwap(0, 1, &alreadyFetched))
-    return (NULL);
-
-  if (newData)
-  {
-    IOMemoryDescriptor * data = newData;
-    newData = NULL;
-    return (data);
-  }  
-
-  DEBG("%s: data at address %u size %u\n", __func__,
-       args->keyStoreDataStart,
-       args->keyStoreDataSize);
-
-  if (args->keyStoreDataStart == 0)
-    return (NULL);
-
-  ranges.address = args->keyStoreDataStart;
-  ranges.length = args->keyStoreDataSize;
-
-  options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
-  
-  memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges,
-                                                    1,
-                                                    0,
-                                                    NULL,
-                                                    options);
-
-  DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
-
-  return memoryDescriptor;
+       IOMemoryDescriptor *memoryDescriptor;
+       boot_args *args = (boot_args *)PE_state.bootArgs;
+       IOOptionBits options;
+       IOAddressRange ranges;
+
+       if (!OSCompareAndSwap(0, 1, &alreadyFetched)) {
+               return NULL;
+       }
+
+       if (newData) {
+               IOMemoryDescriptor * data = newData;
+               newData = NULL;
+               return data;
+       }
+
+       DEBG("%s: data at address %u size %u\n", __func__,
+           args->keyStoreDataStart,
+           args->keyStoreDataSize);
+
+       if (args->keyStoreDataStart == 0) {
+               return NULL;
+       }
+
+       ranges.address = args->keyStoreDataStart;
+       ranges.length = args->keyStoreDataSize;
+
+       options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
+
+       memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges,
+           1,
+           0,
+           NULL,
+           options);
+
+       DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
+
+       return memoryDescriptor;
+}
+
+// APFS volume key fetcher
+
+// Store in-memory key (could be used by IOHibernateDone)
+void
+IOSetAPFSKeyStoreData(IOMemoryDescriptor* data)
+{
+       // Do not allow re-fetching of the boot_args key by passing NULL here.
+       if (data != NULL) {
+               apfsKeyData = data;
+               apfsKeyFetched = 0;
+       }
+}
+
+// Retrieve any key we may have (stored in boot_args or by Hibernate)
+IOMemoryDescriptor*
+IOGetAPFSKeyStoreData()
+{
+       // Check if someone got the key before us
+       if (!OSCompareAndSwap(0, 1, &apfsKeyFetched)) {
+               return NULL;
+       }
+
+       // Do we have in-memory key?
+       if (apfsKeyData) {
+               IOMemoryDescriptor* data = apfsKeyData;
+               apfsKeyData = NULL;
+               return data;
+       }
+
+       // Looks like there was no in-memory key and it's the first call - try boot_args
+       boot_args* args = (boot_args*)PE_state.bootArgs;
+
+       DEBG("%s: data at address %u size %u\n", __func__, args->apfsDataStart, args->apfsDataSize);
+       if (args->apfsDataStart == 0) {
+               return NULL;
+       }
+
+       // We have the key in the boot_args, create IOMemoryDescriptor for the blob
+       IOAddressRange ranges;
+       ranges.address = args->apfsDataStart;
+       ranges.length = args->apfsDataSize;
+
+       const IOOptionBits options = kIODirectionInOut | kIOMemoryTypePhysical64 | kIOMemoryMapperNone;
+
+       IOMemoryDescriptor* memoryDescriptor = IOMemoryDescriptor::withOptions(&ranges, 1, 0, NULL, options);
+       DEBG("%s: memory descriptor %p\n", __func__, memoryDescriptor);
+       return memoryDescriptor;
 }