]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOPolledInterface.cpp
xnu-7195.101.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOPolledInterface.cpp
index d36c0c6db75fdafc64a378cb11b499d1c13d159c..9ff9f8043c7631244f9bca0f29e6d333701a357e 100644 (file)
 #include <IOKit/IOHibernatePrivate.h>
 #include <IOKit/IOBufferMemoryDescriptor.h>
 #include <IOKit/AppleKeyStoreInterface.h>
+#include <libkern/c++/OSSharedPtr.h>
 #include "IOKitKernelInternal.h"
 
+#if defined(__arm64__)
+#include <pexpert/arm64/board_config.h>
+#if XNU_MONITOR_PPL_HIB
+#include <IOKit/SEPHibernator.h>
+#endif /* XNU_MONITOR_PPL_HIB */
+#endif /* defined(__arm64__) */
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 OSDefineMetaClassAndAbstractStructors(IOPolledInterface, OSObject);
 
-OSMetaClassDefineReservedUsed(IOPolledInterface, 0);
+OSMetaClassDefineReservedUsedX86(IOPolledInterface, 0);
 OSMetaClassDefineReservedUnused(IOPolledInterface, 1);
 OSMetaClassDefineReservedUnused(IOPolledInterface, 2);
 OSMetaClassDefineReservedUnused(IOPolledInterface, 3);
@@ -486,6 +493,9 @@ IOCopyMediaForDev(dev_t device)
        return result;
 }
 
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if defined(__i386__) || defined(__x86_64__)
 #define APFSMEDIA_GETHIBERKEY         "getHiberKey"
 
 static IOReturn
@@ -570,6 +580,20 @@ IOGetVolumeCryptKey(dev_t block_dev,
        part->release();
        return err;
 }
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if defined(__arm64__)
+static IOReturn
+IOGetHibernationCryptKey(uint8_t * hibernationKey,
+    size_t * keySize,
+    uint32_t *swSeed
+    )
+{
+       return kIOReturnNotFound;
+}
+#endif /* defined(__arm64__) */
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -671,15 +695,36 @@ IOPolledFileOpen(const char * filename,
                    vars->pollers->pollers->getCount());
 
                OSString * keyUUID = NULL;
+#if defined(__i386__) || defined(__x86_64__)
                if (volumeCryptKey) {
                        err = IOGetVolumeCryptKey(block_dev, &keyUUID, volumeCryptKey, keySize);
                }
+#elif defined(__arm64__)
+               uint32_t swSeed = 0;
+               if (volumeCryptKey) {
+                       if (flags & kIOPolledFileHibernate) {
+                               err = IOGetHibernationCryptKey(volumeCryptKey, keySize, &swSeed);
+                               if (kIOReturnSuccess != err) {
+                                       HIBLOG("error 0x%x from IOGetHibernationCryptKey\n", err);
+                                       break;
+                               }
+                       } else {
+                               *keySize = 0;
+                       }
+               }
+#else
+               if (volumeCryptKey) {
+                       HIBLOG("IOPolledFileOpen: unable to get volumeCryptKey\n");
+                       err = kIOReturnNotFound;
+                       break;
+               }
+#endif
 
                *fileVars    = vars;
                vars->fileExtents = extentsData;
 
                // make imagePath
-               OSData * data;
+               OSData * data = NULL;
                if (imagePath) {
 #if defined(__i386__) || defined(__x86_64__)
                        char str2[24 + sizeof(uuid_string_t) + 2];
@@ -695,9 +740,13 @@ IOPolledFileOpen(const char * filename,
                                gIOCreateEFIDevicePathSymbol, false,
                                (void *) part, (void *) str2,
                                (void *) (uintptr_t) true, (void *) &data);
-#else
-                       data = NULL;
+#elif defined(__arm64__)
+                       char str2[26];
+                       snprintf(str2, sizeof(str2), "%qx:%x", vars->extentMap[0].start, swSeed);
+                       data = OSData::withBytes(str2, (unsigned int) strlen(str2));
                        err = kIOReturnSuccess;
+#else
+                       err = kIOReturnNotFound;
 #endif
                        if (kIOReturnSuccess != err) {
                                HIBLOG("error 0x%x getting path\n", err);
@@ -728,6 +777,22 @@ IOPolledFileOpen(const char * filename,
        return err;
 }
 
+IOReturn
+IOPolledFileOpen(const char * filename,
+    uint32_t flags,
+    uint64_t setFileSize, uint64_t fsFreeSize,
+    void * write_file_addr, size_t write_file_len,
+    IOPolledFileIOVars ** fileVars,
+    OSSharedPtr<OSData>& imagePath,
+    uint8_t * volumeCryptKey, size_t * keySize)
+{
+       OSData* imagePathRaw = NULL;
+       IOReturn result = IOPolledFileOpen(filename, flags, setFileSize, fsFreeSize, write_file_addr, write_file_len,
+           fileVars, &imagePathRaw, volumeCryptKey, keySize);
+       imagePath.reset(imagePathRaw, OSNoRetain);
+       return result;
+}
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 IOReturn
@@ -793,10 +858,11 @@ IOPolledFilePollersSetup(IOPolledFileIOVars * vars,
                vars->buffer       = (uint8_t *) vars->pollers->ioBuffer->getBytesNoCopy();
                vars->bufferHalf   = 0;
                vars->bufferOffset = 0;
-               vars->bufferSize   = (vars->pollers->ioBuffer->getLength() >> 1);
+               assert(vars->pollers->ioBuffer->getLength() <= UINT_MAX);
+               vars->bufferSize   = (typeof(vars->bufferSize))(vars->pollers->ioBuffer->getLength() >> 1);
 
                if (vars->maxiobytes < vars->bufferSize) {
-                       vars->bufferSize = vars->maxiobytes;
+                       vars->bufferSize = (typeof(vars->bufferSize))vars->maxiobytes;
                }
        }while (false);
 
@@ -836,7 +902,7 @@ IOPolledFileSeek(IOPolledFileIOVars * vars, uint64_t position)
        if (vars->bufferSize <= vars->extentRemaining) {
                vars->bufferLimit = vars->bufferSize;
        } else {
-               vars->bufferLimit = vars->extentRemaining;
+               vars->bufferLimit = ((uint32_t) vars->extentRemaining);
        }
 
        return kIOReturnSuccess;
@@ -861,8 +927,6 @@ IOPolledFileWrite(IOPolledFileIOVars * vars,
                                size = vars->blockSize - size;
                        }
                        flush = true;
-                       // use some garbage for the fill
-                       bytes = vars->buffer + vars->bufferOffset;
                }
 
                copy = vars->bufferLimit - vars->bufferOffset;
@@ -914,10 +978,11 @@ IOPolledFileWrite(IOPolledFileIOVars * vars,
 
                                clock_get_uptime(&startTime);
 
+                               assert(encryptLen <= UINT_MAX);
                                // encrypt the buffer
                                aes_encrypt_cbc(vars->buffer + vars->bufferHalf + encryptStart,
                                    &cryptvars->aes_iv[0],
-                                   encryptLen / AES_BLOCK_SIZE,
+                                   (unsigned int) (encryptLen / AES_BLOCK_SIZE),
                                    vars->buffer + vars->bufferHalf + encryptStart,
                                    &cryptvars->ctx.encrypt);
 
@@ -963,7 +1028,7 @@ IOPolledFileWrite(IOPolledFileIOVars * vars,
                        if (vars->bufferSize <= vars->extentRemaining) {
                                vars->bufferLimit = vars->bufferSize;
                        } else {
-                               vars->bufferLimit = vars->extentRemaining;
+                               vars->bufferLimit =  ((uint32_t) vars->extentRemaining);
                        }
 
                        if (!vars->extentRemaining) {
@@ -1059,17 +1124,17 @@ IOPolledFileRead(IOPolledFileIOVars * vars,
                                }
                        }
 
-                       uint64_t length;
-                       uint64_t lastReadLength = vars->lastRead;
+                       uint32_t length;
+                       uint32_t lastReadLength = vars->lastRead;
                        uint64_t offset = (vars->position
                            - vars->extentPosition + vars->currentExtent->start);
                        if (vars->extentRemaining <= vars->bufferSize) {
-                               length = vars->extentRemaining;
+                               length =  ((uint32_t) vars->extentRemaining);
                        } else {
                                length = vars->bufferSize;
                        }
                        if ((length + vars->position) > vars->readEnd) {
-                               length = vars->readEnd - vars->position;
+                               length = ((uint32_t) (vars->readEnd - vars->position));
                        }
 
                        vars->lastRead = length;
@@ -1098,9 +1163,10 @@ IOPolledFileRead(IOPolledFileIOVars * vars,
                                // decrypt the buffer
                                clock_get_uptime(&startTime);
 
+                               assert(lastReadLength <= UINT_MAX);
                                aes_decrypt_cbc(vars->buffer + vars->bufferHalf,
                                    &thisVector[0],
-                                   lastReadLength / AES_BLOCK_SIZE,
+                                   (unsigned int) (lastReadLength / AES_BLOCK_SIZE),
                                    vars->buffer + vars->bufferHalf,
                                    &cryptvars->ctx.decrypt);