CFDictionaryRef device_info(int socket, CFDictionaryRef request) { uint8_t dkey[40]={0}; uint8_t emf[36]={0}; struct HFSInfos hfsinfos={0}; CFMutableDictionaryRef out = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); get_device_infos(out); getHFSInfos(&hfsinfos); /* printf("NAND block size : %x\n", hfsinfos.blockSize); printf("Data volume UUID : %llx\n", CFSwapInt64BigToHost(hfsinfos.volumeUUID)); printf("Data volume offset : %x\n", hfsinfos.dataVolumeOffset); */ uint8_t* key835 = IOAES_key835(); uint8_t* key89B = IOAES_key89B(); if (!AppleEffaceableStorage__getBytes(lockers, 960)) { CFDataRef lockersData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, lockers, 960, kCFAllocatorNull); CFDictionaryAddValue(out, CFSTR("lockers"), lockersData); CFRelease(lockersData); if (!AppleEffaceableStorage__getLockerFromBytes(LOCKER_DKEY, lockers, 960, dkey, 40)) { aes_key_wrap_ctx ctx; aes_key_wrap_set_key(&ctx, key835, 16); if(aes_key_unwrap(&ctx, dkey, dkey, 32/8)) printf("FAIL unwrapping DKey with key 0x835\n"); } if (!AppleEffaceableStorage__getLockerFromBytes(LOCKER_EMF, lockers, 960, emf, 36)) { doAES(&emf[4], &emf[4], 32, kIOAESAcceleratorCustomMask, key89B, NULL, kIOAESAcceleratorDecrypt, 128); } else if (!AppleEffaceableStorage__getLockerFromBytes(LOCKER_LWVM, lockers, 960, lwvm, 0x50)) { doAES(lwvm, lwvm, 0x50, kIOAESAcceleratorCustomMask, key89B, NULL, kIOAESAcceleratorDecrypt, 128); memcpy(&emf[4], &lwvm[32+16], 32); } } CFNumberRef n = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &hfsinfos.dataVolumeOffset); CFDictionaryAddValue(out, CFSTR("dataVolumeOffset"), n); CFRelease(n); addHexaString(out, CFSTR("dataVolumeUUID"), (uint8_t*) &hfsinfos.volumeUUID, 8); addHexaString(out, CFSTR("key835"), key835, 16); addHexaString(out, CFSTR("key89B"), key89B, 16); addHexaString(out, CFSTR("EMF"), &emf[4], 32); addHexaString(out, CFSTR("DKey"), dkey, 32); return out; }
void aes_decrypt(void* data, int size, AESKeyType keyType, const void* key, AESKeyLen keyLen, const void* iv) { doAES(0x11, data, size, keyType, key, keyLen, iv); }
AbstractFile* createAbstractFileFromImg3(AbstractFile* file) { AbstractFile* toReturn; Img3Info* info; Img3Element* current; if(!file) { return NULL; } file->seek(file, 0); info = (Img3Info*) malloc(sizeof(Img3Info)); info->file = file; info->root = readImg3Element(file); info->data = NULL; info->cert = NULL; info->kbag = NULL; info->type = NULL; info->shsh = NULL; info->ecid = NULL; info->encrypted = FALSE; current = (Img3Element*) info->root->data; while(current != NULL) { if(current->header->magic == IMG3_DATA_MAGIC) { info->data = current; } if(current->header->magic == IMG3_CERT_MAGIC) { info->cert = current; } if(current->header->magic == IMG3_TYPE_MAGIC) { info->type = current; } if(current->header->magic == IMG3_SHSH_MAGIC) { info->shsh = current; } if(current->header->magic == IMG3_ECID_MAGIC) { info->ecid = current; } if(current->header->magic == IMG3_KBAG_MAGIC && ((AppleImg3KBAGHeader*)current->data)->key_modifier == 1) { info->kbag = current; } current = current->next; } info->offset = 0; info->dirty = FALSE; info->encrypted = FALSE; info->decryptLast = FALSE; toReturn = (AbstractFile*) malloc(sizeof(AbstractFile2)); toReturn->data = info; toReturn->read = readImg3; toReturn->write = writeImg3; toReturn->seek = seekImg3; toReturn->tell = tellImg3; toReturn->getLength = getLengthImg3; toReturn->close = closeImg3; toReturn->type = AbstractFileTypeImg3; AbstractFile2* abstractFile2 = (AbstractFile2*) toReturn; abstractFile2->setKey = setKeyImg3; if(info->kbag) { uint8_t* keySeed; uint32_t keySeedLen; keySeedLen = 16 + (((AppleImg3KBAGHeader*)info->kbag->data)->key_bits)/8; keySeed = (uint8_t*) malloc(keySeedLen); memcpy(keySeed, (uint8_t*)((AppleImg3KBAGHeader*)info->kbag->data) + sizeof(AppleImg3KBAGHeader), keySeedLen); #ifdef HAVE_HW_CRYPTO printf("Have hardware crypto\n"); CFMutableDictionaryRef dict = IOServiceMatching("IOAESAccelerator"); io_service_t dev = IOServiceGetMatchingService(kIOMasterPortDefault, dict); io_connect_t conn = 0; IOServiceOpen(dev, mach_task_self(), 0, &conn); int i; printf("KeySeed: "); for(i = 0; i < keySeedLen; i++) { printf("%02x", keySeed[i]); } printf("\n"); if(doAES(conn, keySeed, keySeed, keySeedLen, GID, NULL, NULL, kIOAESAcceleratorDecrypt) == 0) { unsigned int key[keySeedLen - 16]; unsigned int iv[16]; printf("IV: "); for(i = 0; i < 16; i++) { iv[i] = keySeed[i]; printf("%02x", iv[i]); } printf("\n"); printf("Key: "); for(i = 0; i < (keySeedLen - 16); i++) { key[i] = keySeed[i + 16]; printf("%02x", key[i]); } printf("\n"); setKeyImg3(abstractFile2, key, iv); } IOServiceClose(conn); IOObjectRelease(dev); #else int i = 0; char outputBuffer[256]; char curBuffer[256]; outputBuffer[0] = '\0'; for(i = 0; i < keySeedLen; i++) { sprintf(curBuffer, "%02x", keySeed[i]); strcat(outputBuffer, curBuffer); } strcat(outputBuffer, "\n"); XLOG(4, outputBuffer); #endif free(keySeed); } return toReturn; }
IOReturn doAES_wrapper(void* thisxxx, int mode, void* iv, void* outbuf, void *inbuf, uint32_t size, uint32_t keyMask) { int x = doAES(inbuf, outbuf, size, keyMask, NULL, iv, mode, 128); return !x; }
CFDictionaryRef remote_aes(int socket, CFDictionaryRef dict) { uint8_t* input2 = NULL; uint32_t len = 0; uint8_t* iv2 = NULL; uint32_t keyMask = 0; uint32_t mode = 0; uint32_t bits = 0; CFNumberRef km = CFDictionaryGetValue(dict, CFSTR("keyMask")); if(km == NULL || CFGetTypeID(km) != CFNumberGetTypeID()) return NULL; CFNumberGetValue(km, kCFNumberIntType, &keyMask); CFNumberRef m = CFDictionaryGetValue(dict, CFSTR("mode")); if(m == NULL || CFGetTypeID(m) != CFNumberGetTypeID()) return NULL; CFNumberGetValue(m, kCFNumberIntType, &mode); CFNumberRef b = CFDictionaryGetValue(dict, CFSTR("bits")); if(b == NULL || CFGetTypeID(b) != CFNumberGetTypeID()) return NULL; CFNumberGetValue(b, kCFNumberIntType, &bits); CFDataRef input = CFDictionaryGetValue(dict, CFSTR("input")); if(input == NULL || CFGetTypeID(input) != CFDataGetTypeID()) return NULL; CFDataRef iv = CFDictionaryGetValue(dict, CFSTR("iv")); if(iv != NULL) { if (CFGetTypeID(iv) != CFDataGetTypeID()) return NULL; iv2 = (uint8_t*) CFDataGetBytePtr(iv); } len = CFDataGetLength(input); if (len % 16 != 0) { return NULL; } input2 = malloc(len); if (input2 == NULL) { return NULL; } memcpy(input2, CFDataGetBytePtr(input), len); uint32_t ret = doAES(input2, input2, len, keyMask, NULL, iv2, mode, bits); CFMutableDictionaryRef out = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFNumberRef retCode = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ret); CFDictionaryAddValue(out, CFSTR("returnCode"), retCode); CFRelease(retCode); if (ret == 0) { CFDataRef dd = CFDataCreate(kCFAllocatorDefault, input2, len); CFDictionaryAddValue(out, CFSTR("data"), dd); CFRelease(dd); } free(input2); return out; }