unsigned int images_read(Image* image, void** data) { if(image == NULL) { *data = NULL; return 0; } *data = malloc(image->padded); if(!IsImg3) { nor_read(*data, image->offset + sizeof(Img2Header), image->length); aes_838_decrypt(*data, image->length, NULL); return image->length; } else { nor_read(*data, image->offset, image->padded); uint32_t dataOffset = 0; uint32_t dataLength = 0; uint32_t kbagOffset = 0; uint32_t kbagLength = 0; uint32_t offset = (uint32_t)(*data + sizeof(AppleImg3RootHeader)); while((offset - (uint32_t)(*data + sizeof(AppleImg3RootHeader))) < image->length) { AppleImg3Header* header = (AppleImg3Header*) offset; if(header->magic == IMG3_DATA_MAGIC) { dataOffset = offset + sizeof(AppleImg3Header); dataLength = header->dataSize; } if(header->magic == IMG3_KBAG_MAGIC) { kbagOffset = offset + sizeof(AppleImg3Header); kbagLength = header->dataSize; } offset += header->size; } AppleImg3KBAGHeader* kbag = (AppleImg3KBAGHeader*) kbagOffset; if(kbag != 0) { if(kbag->key_modifier == 1) { aes_decrypt((void*)(kbagOffset + sizeof(AppleImg3KBAGHeader)), 16 + (kbag->key_bits / 8), AESGID, NULL, NULL); } aes_decrypt((void*)dataOffset, (dataLength / 16) * 16, AESCustom, (uint8_t*)(kbagOffset + sizeof(AppleImg3KBAGHeader) + 16), (uint8_t*)(kbagOffset + sizeof(AppleImg3KBAGHeader))); } uint8_t* newBuf = malloc(dataLength); memcpy(newBuf, (void*)dataOffset, dataLength); free(*data); *data = newBuf; return dataLength; } }
unsigned int images_read(Image* image, void** data) { if(image == NULL) { *data = NULL; return 0; } mtd_t *dev = images_device(); if(!dev) { *data = NULL; return 0; } mtd_prepare(dev); *data = malloc(image->padded); if(!IsImg3) { mtd_read(dev, *data, image->offset + sizeof(Img2Header), image->length); aes_838_decrypt(*data, image->length, NULL); mtd_finish(dev); return image->length; } else { mtd_read(dev, *data, image->offset, image->padded); uint32_t dataOffset = 0; uint32_t dataLength = 0; uint32_t kbagOffset = 0; uint32_t kbagLength = 0; uint32_t offset = (uint32_t)(*data + sizeof(AppleImg3RootHeader)); while((offset - (uint32_t)(*data + sizeof(AppleImg3RootHeader))) < image->length) { AppleImg3Header* header = (AppleImg3Header*) offset; if(header->magic == IMG3_DATA_MAGIC) { dataOffset = offset + sizeof(AppleImg3Header); dataLength = header->dataSize; } if(header->magic == IMG3_KBAG_MAGIC) { kbagOffset = offset + sizeof(AppleImg3Header); kbagLength = header->dataSize; } offset += header->size; } AppleImg3KBAGHeader* kbag = (AppleImg3KBAGHeader*) kbagOffset; if(kbag != 0) { if(kbag->key_modifier == 1) { aes_decrypt((void*)(kbagOffset + sizeof(AppleImg3KBAGHeader)), 16 + (kbag->key_bits / 8), AESGID, NULL, 0, NULL); } AESKeyLen keyLen; switch(kbag->key_bits) { case 128: keyLen = AES128; break; case 192: keyLen = AES192; break; case 256: keyLen = AES256; break; default: keyLen = AES128; break; } aes_decrypt((void*)dataOffset, (dataLength / 16) * 16, AESCustom, (uint8_t*)(kbagOffset + sizeof(AppleImg3KBAGHeader) + 16), keyLen, (uint8_t*)(kbagOffset + sizeof(AppleImg3KBAGHeader))); } uint8_t* newBuf = malloc(dataLength); memcpy(newBuf, (void*)dataOffset, dataLength); free(*data); *data = newBuf; mtd_finish(dev); return dataLength; } }