Skip to content

Commit

Permalink
restore: AS: Add support for updating AppleTCON
Browse files Browse the repository at this point in the history
Closes: libimobiledevice#442

Co-authored-by: Nikias Bassen <nikias@gmx.li>
Signed-off-by: Hector Martin <marcan@marcan.st>
  • Loading branch information
marcan and nikias committed Sep 26, 2021
1 parent 8bdfec9 commit 3fe0564
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/restore.c
Expand Up @@ -107,6 +107,7 @@
#define INSTALLING_RECOVERY_OS_IMAGE 71
#define REQUESTING_EAN_DATA 74
#define SEALING_SYSTEM_VOLUME 77
#define UPDATING_APPLETCON 81

static int restore_finished = 0;

Expand Down Expand Up @@ -625,6 +626,8 @@ const char* restore_progress_string(unsigned int operation)
return "Requesting EAN Data";
case SEALING_SYSTEM_VOLUME:
return "Sealing System Volume";
case UPDATING_APPLETCON:
return "Updating AppleTCON";
default:
return "Unknown operation";
}
Expand Down Expand Up @@ -2602,6 +2605,77 @@ static plist_t restore_get_veridian_firmware_data(restored_client_t restore, str
return response;
}

static plist_t restore_get_tcon_firmware_data(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity, plist_t p_info)
{
char *comp_name = "Baobab,TCON";
char *comp_path = NULL;
plist_t comp_node = NULL;
unsigned char* component_data = NULL;
unsigned int component_size = 0;
plist_t parameters = NULL;
plist_t request = NULL;
plist_t response = NULL;
plist_t node = NULL;
int ret;

/* create Baobab request */
request = tss_request_new(NULL);
if (request == NULL) {
error("ERROR: Unable to create Baobab TSS request\n");
free(component_data);
return NULL;
}

parameters = plist_new_dict();

/* add manifest for current build_identity to parameters */
tss_parameters_add_from_manifest(parameters, build_identity);

/* add Baobab,* tags from info dictionary to parameters */
plist_dict_merge(&parameters, p_info);

/* add required tags for Baobab TSS request */
tss_request_add_tcon_tags(request, parameters, NULL);

plist_free(parameters);

info("Sending Baobab TSS request...\n");
response = tss_request_send(request, client->tss_url);
plist_free(request);
if (response == NULL) {
error("ERROR: Unable to fetch Baobab ticket\n");
free(component_data);
return NULL;
}

if (plist_dict_get_item(response, "Baobab,Ticket")) {
info("Received Baobab ticket\n");
} else {
error("ERROR: No 'Baobab,Ticket' in TSS response, this might not work\n");
}

if (build_identity_get_component_path(build_identity, comp_name, &comp_path) < 0) {
error("ERROR: Unable to get path for '%s' component\n", comp_name);
return NULL;
}

/* now get actual component data */
ret = extract_component(client->ipsw, comp_path, &component_data, &component_size);
free(comp_path);
comp_path = NULL;
if (ret < 0) {
error("ERROR: Unable to extract '%s' component\n", comp_name);
return NULL;
}

plist_dict_set_item(response, "FirmwareData", plist_new_data((char *)component_data, (uint64_t)component_size));
free(component_data);
component_data = NULL;
component_size = 0;

return response;
}

static int restore_send_firmware_updater_data(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity, plist_t message)
{
plist_t arguments;
Expand Down Expand Up @@ -2689,6 +2763,12 @@ static int restore_send_firmware_updater_data(restored_client_t restore, struct
error("ERROR: %s: Couldn't get Veridian firmware data\n", __func__);
goto error_out;
}
} else if (strcmp(s_updater_name, "AppleTCON") == 0) {
fwdict = restore_get_tcon_firmware_data(restore, client, build_identity, p_info);
if (fwdict == NULL) {
error("ERROR: %s: Couldn't get AppleTCON firmware data\n", __func__);
goto error_out;
}
} else {
error("ERROR: %s: Got unknown updater name '%s'.\n", __func__, s_updater_name);
goto error_out;
Expand Down
105 changes: 105 additions & 0 deletions src/tss.c
Expand Up @@ -443,6 +443,34 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity)
}
node = NULL;

/* add Baobab,BoardID */
node = plist_dict_get_item(build_identity, "Baobab,BoardID");
if (node) {
plist_dict_set_item(parameters, "Baobab,BoardID", plist_copy(node));
}
node = NULL;

/* add Baobab,ChipID */
node = plist_dict_get_item(build_identity, "Baobab,ChipID");
if (node) {
plist_dict_set_item(parameters, "Baobab,ChipID", plist_copy(node));
}
node = NULL;

/* add Baobab,ManifestEpoch */
node = plist_dict_get_item(build_identity, "Baobab,ManifestEpoch");
if (node) {
plist_dict_set_item(parameters, "Baobab,ManifestEpoch", plist_copy(node));
}
node = NULL;

/* add Baobab,SecurityDomain */
node = plist_dict_get_item(build_identity, "Baobab,SecurityDomain");
if (node) {
plist_dict_set_item(parameters, "Baobab,SecurityDomain", plist_copy(node));
}
node = NULL;

/* add eUICC,ChipID */
node = plist_dict_get_item(build_identity, "eUICC,ChipID");
if (node) {
Expand Down Expand Up @@ -1699,6 +1727,83 @@ int tss_request_add_veridian_tags(plist_t request, plist_t parameters, plist_t o
return 0;
}

int tss_request_add_tcon_tags(plist_t request, plist_t parameters, plist_t overrides)
{
plist_t node = NULL;

plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__);
return -1;
}

/* add tags indicating we want to get the Rap,Ticket */
plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
plist_dict_set_item(request, "@Baobab,Ticket", plist_new_bool(1));

uint64_t u64val = 0;
uint8_t bval = 0;
uint8_t isprod = 0;

u64val = _plist_dict_get_uint(parameters, "Baobab,BoardID");
plist_dict_set_item(request, "Baobab,BoardID", plist_new_uint(u64val));

u64val = _plist_dict_get_uint(parameters, "Baobab,ChipID");
plist_dict_set_item(request, "Baobab,ChipID", plist_new_uint(u64val));

node = plist_dict_get_item(parameters, "Baobab,ECID");
if (node) {
plist_dict_set_item(request, "Baobab,ECID", plist_copy(node));
}

u64val = _plist_dict_get_uint(parameters, "Baobab,Life");
plist_dict_set_item(request, "Baobab,Life", plist_new_uint(u64val));

u64val = _plist_dict_get_uint(parameters, "Baobab,ManifestEpoch");
plist_dict_set_item(request, "Baobab,ManifestEpoch", plist_new_uint(u64val));

isprod = _plist_dict_get_bool(parameters, "Baobab,ProductionMode");
plist_dict_set_item(request, "Baobab,ProductionMode", plist_new_bool(isprod));

u64val = _plist_dict_get_uint(parameters, "Baobab,SecurityDomain");
plist_dict_set_item(request, "Baobab,SecurityDomain", plist_new_uint(u64val));

node = plist_dict_get_item(parameters, "Baobab,UpdateNonce");
if (node) {
plist_dict_set_item(request, "Baobab,UpdateNonce", plist_copy(node));
}

char *comp_name = NULL;
plist_dict_iter iter = NULL;
plist_dict_new_iter(manifest_node, &iter);
while (iter) {
node = NULL;
comp_name = NULL;
plist_dict_next_item(manifest_node, iter, &comp_name, &node);
if (comp_name == NULL) {
node = NULL;
break;
}
if (strncmp(comp_name, "Baobab,", 7) == 0) {
plist_t manifest_entry = plist_copy(node);

plist_dict_remove_item(manifest_entry, "Info");
plist_dict_set_item(manifest_entry, "EPRO", plist_new_bool(isprod));

/* finally add entry to request */
plist_dict_set_item(request, comp_name, manifest_entry);
}
free(comp_name);
}
free(iter);

/* apply overrides */
if (overrides) {
plist_dict_merge(&request, overrides);
}
return 0;
}

static size_t tss_write_callback(char* data, size_t size, size_t nmemb, tss_response* response) {
size_t total = size * nmemb;
if (total != 0) {
Expand Down
1 change: 1 addition & 0 deletions src/tss.h
Expand Up @@ -47,6 +47,7 @@ int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t ov
int tss_request_add_vinyl_tags(plist_t request, plist_t parameters, plist_t overrides);
int tss_request_add_rose_tags(plist_t request, plist_t parameters, plist_t overrides);
int tss_request_add_veridian_tags(plist_t request, plist_t parameters, plist_t overrides);
int tss_request_add_tcon_tags(plist_t request, plist_t parameters, plist_t overrides);

int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters);
int tss_request_add_ap_img3_tags(plist_t request, plist_t parameters);
Expand Down

0 comments on commit 3fe0564

Please sign in to comment.