#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);
return result;
}
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#if defined(__i386__) || defined(__x86_64__)
#define APFSMEDIA_GETHIBERKEY "getHiberKey"
static IOReturn
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__) */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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];
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);
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
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);
if (vars->bufferSize <= vars->extentRemaining) {
vars->bufferLimit = vars->bufferSize;
} else {
- vars->bufferLimit = vars->extentRemaining;
+ vars->bufferLimit = ((uint32_t) vars->extentRemaining);
}
return kIOReturnSuccess;
size = vars->blockSize - size;
}
flush = true;
- // use some garbage for the fill
- bytes = vars->buffer + vars->bufferOffset;
}
copy = vars->bufferLimit - vars->bufferOffset;
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);
if (vars->bufferSize <= vars->extentRemaining) {
vars->bufferLimit = vars->bufferSize;
} else {
- vars->bufferLimit = vars->extentRemaining;
+ vars->bufferLimit = ((uint32_t) vars->extentRemaining);
}
if (!vars->extentRemaining) {
}
}
- 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;
// 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);