Files
QEMU-S5L8950X/scripts/patches/idevicerestore-qemu-lab-boot.patch
T
Yaya48 5d9a60a926 hw/arm: add authenticated A6 IMG3 boot lab
Model the A6 crypto, interrupt, USB, and platform blocks needed to boot SecureROM through iBSS into iBEC Recovery.

Add local lab identity, IMG3, and APTicket tooling, patched macOS recovery utilities, UART and GDB access, and English end-user documentation.
2026-09-01 09:51:49 -07:00

117 lines
5.0 KiB
Diff

--- a/src/dfu.c
+++ b/src/dfu.c
@@ -127,6 +127,9 @@
int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component)
{
char* path = NULL;
+ const char* qemu_lab_dir = getenv("IDEVICERESTORE_QEMU_LAB_DIR");
+ int qemu_lab_component = qemu_lab_dir && qemu_lab_dir[0] &&
+ (!strcmp(component, "iBSS") || !strcmp(component, "iBEC"));
// Use a specific TSS ticket for the Ap,LocalPolicy component
plist_t tss = client->tss;
@@ -137,7 +140,26 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
void* component_data = NULL;
size_t component_size = 0;
- if (strcmp(component, "Ap,LocalPolicy") == 0) {
+ if (qemu_lab_component) {
+ const char* filename = !strcmp(component, "iBSS") ?
+ "iBSS.chain-encrypted.dfu" :
+ "iBEC.chain-nonce-encrypted.dfu";
+ size_t path_size = strlen(qemu_lab_dir) + strlen(filename) + 2;
+ path = malloc(path_size);
+ if (!path) {
+ logger(LL_ERROR, "Out of memory\n");
+ return -1;
+ }
+ snprintf(path, path_size, "%s/%s", qemu_lab_dir, filename);
+ if (read_file(path, &component_data, &component_size) < 0) {
+ logger(LL_ERROR, "Unable to read QEMU lab %s from %s\n", component, path);
+ free(path);
+ return -1;
+ }
+ logger(LL_INFO, "Using QEMU lab %s from %s\n", component, path);
+ free(path);
+ path = NULL;
+ } else if (strcmp(component, "Ap,LocalPolicy") == 0) {
// If Ap,LocalPolicy => Inject an empty policy
component_data = malloc(sizeof(lpol_file));
component_size = sizeof(lpol_file);
@@ -168,7 +190,11 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
void* data = NULL;
size_t size = 0;
- if (personalize_component(client, component, component_data, component_size, tss, &data, &size) < 0) {
+ if (qemu_lab_component) {
+ data = component_data;
+ size = component_size;
+ component_data = NULL;
+ } else if (personalize_component(client, component, component_data, component_size, tss, &data, &size) < 0) {
logger(LL_ERROR, "Unable to get personalized component: %s\n", component);
free(component_data);
return -1;
@@ -176,7 +202,7 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide
free(component_data);
component_data = NULL;
- if (!client->image4supported && client->build_major > 8 && !(client->flags & FLAG_CUSTOM) && !strcmp(component, "iBEC")) {
+ if (!qemu_lab_component && !client->image4supported && client->build_major > 8 && !(client->flags & FLAG_CUSTOM) && !strcmp(component, "iBEC")) {
unsigned char* ticket = NULL;
unsigned int tsize = 0;
if (tss_response_get_ap_ticket(client->tss, &ticket, &tsize) < 0) {
@@ -517,7 +543,8 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide
logger(LL_INFO, "Nonce: ");
logger_dump_hex(LL_INFO, client->nonce, client->nonce_size);
- if (nonce_changed && !(client->flags & FLAG_CUSTOM)) {
+ if (nonce_changed && !(client->flags & FLAG_CUSTOM) &&
+ !getenv("IDEVICERESTORE_QEMU_LAB_DIR")) {
// Welcome iOS5. We have to re-request the TSS with our nonce.
plist_free(client->tss);
if (get_tss_response(client, build_identity, &client->tss) < 0) {
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -682,6 +682,11 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
tss_enabled = 0;
logger(LL_INFO, "Custom firmware requested; TSS has been disabled.\n");
}
+ if (getenv("IDEVICERESTORE_QEMU_LAB_DIR")) {
+ /* The QEMU wrapper supplies locally personalized iBSS/iBEC images. */
+ tss_enabled = 0;
+ logger(LL_INFO, "QEMU lab boot requested; external TSS has been disabled.\n");
+ }
if (client->mode == MODE_RESTORE) {
if (!(client->flags & FLAG_ALLOW_RESTORE_MODE)) {
@@ -1111,11 +1116,16 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
/* check if all components we need are actually there */
logger(LL_INFO, "Checking IPSW for required components...\n");
- if (build_identity_check_components_in_ipsw(build_identity, client->ipsw) < 0) {
+ if (!getenv("IDEVICERESTORE_QEMU_LAB_BOOT_ONLY") &&
+ build_identity_check_components_in_ipsw(build_identity, client->ipsw) < 0) {
logger(LL_ERROR, "Could not find all required components in IPSW %s\n", client->ipsw->path);
return -1;
}
- logger(LL_INFO, "All required components found in IPSW\n");
+ if (getenv("IDEVICERESTORE_QEMU_LAB_BOOT_ONLY")) {
+ logger(LL_INFO, "QEMU lab boot only needs BuildManifest plus local iBSS/iBEC.\n");
+ } else {
+ logger(LL_INFO, "All required components found in IPSW\n");
+ }
/* Get OS (filesystem) name from build identity */
char* os_path = NULL;
@@ -1466,6 +1476,10 @@ int idevicerestore_start(struct idevicerestore_client_t* client)
mutex_unlock(&client->device_event_mutex);
}
idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.5);
+ if (getenv("IDEVICERESTORE_QEMU_LAB_BOOT_ONLY")) {
+ logger(LL_INFO, "QEMU lab iBEC is running in Recovery mode.\n");
+ return 0;
+ }
if (client->flags & FLAG_QUIT) {
return -1;
}