summaryrefslogtreecommitdiffstats
path: root/src/tss.c
diff options
context:
space:
mode:
authorGravatar Benjamin BOURGEAIS2021-05-06 17:32:09 +0200
committerGravatar Benjamin BOURGEAIS2021-05-08 14:16:50 +0200
commitb936ff28a6882c4da537473197673bb1520d8ce7 (patch)
treee6c69513f243696803cb0d7d4ee75d351db10db3 /src/tss.c
parent8355304866d2e7ead2680725c11d013712d7d19b (diff)
downloadidevicerestore-b936ff28a6882c4da537473197673bb1520d8ce7.tar.gz
idevicerestore-b936ff28a6882c4da537473197673bb1520d8ce7.tar.bz2
tss: Add new calls
- Local policy (non persistent) - recoveryOS - recoveryOS Local policy (persistent) The local policy TSS request differs slightly between the one for the restore process and the recoveryOS. The one for the restore process is meant to be used only once, and the one for the recovery os is meant to be loaded from disk, and thus has a different request. See the Ap,LocalBoot parameter.
Diffstat (limited to 'src/tss.c')
-rw-r--r--src/tss.c345
1 files changed, 342 insertions, 3 deletions
diff --git a/src/tss.c b/src/tss.c
index fecfd0f..4881343 100644
--- a/src/tss.c
+++ b/src/tss.c
@@ -35,7 +35,7 @@
#include "endianness.h"
-#define TSS_CLIENT_VERSION_STRING "libauthinstall-698.0.5"
+#define TSS_CLIENT_VERSION_STRING "libauthinstall-776.60.1"
#define ECID_STRSIZE 0x20
typedef struct {
@@ -58,7 +58,7 @@ plist_t tss_request_new(plist_t overrides) {
plist_t request = plist_new_dict();
- plist_dict_set_item(request, "@Locality", plist_new_string("en_US"));
+ plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));
plist_dict_set_item(request, "@HostPlatformInfo",
#ifdef WIN32
plist_new_string("windows")
@@ -82,6 +82,116 @@ plist_t tss_request_new(plist_t overrides) {
return request;
}
+int tss_request_add_local_policy_tags(plist_t request, plist_t parameters)
+{
+ plist_t node = NULL;
+
+ plist_dict_set_item(request, "@ApImg4Ticket", plist_new_bool(1));
+
+ /* Ap,LocalBoot */
+ node = plist_dict_get_item(parameters, "Ap,LocalBoot");
+ if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) {
+ error("ERROR: Unable to find required Ap,LocalBoot in parameters\n");
+ return -1;
+ }
+ plist_dict_set_item(request, "Ap,LocalBoot", plist_copy(node));
+ node = NULL;
+
+ /* Ap,LocalPolicy */
+ node = plist_dict_get_item(parameters, "Ap,LocalPolicy");
+ if (!node || plist_get_node_type(node) != PLIST_DICT) {
+ error("ERROR: Unable to find required Ap,LocalPolicy in parameters\n");
+ return -1;
+ }
+ plist_dict_set_item(request, "Ap,LocalPolicy", plist_copy(node));
+ node = NULL;
+
+ /* Ap,NextStageIM4MHash */
+ node = plist_dict_get_item(parameters, "Ap,NextStageIM4MHash");
+ if (!node || plist_get_node_type(node) != PLIST_DATA) {
+ error("ERROR: Unable to find required Ap,NextStageIM4MHash in parameters\n");
+ return -1;
+ }
+ plist_dict_set_item(request, "Ap,NextStageIM4MHash", plist_copy(node));
+ node = NULL;
+
+ /* Ap,RecoveryOSPolicyNonceHash */
+ node = plist_dict_get_item(parameters, "Ap,RecoveryOSPolicyNonceHash");
+ if (node) {
+ plist_dict_set_item(request, "Ap,RecoveryOSPolicyNonceHash", plist_copy(node));
+ }
+ node = NULL;
+
+ /* Ap,VolumeUUID */
+ node = plist_dict_get_item(parameters, "Ap,VolumeUUID");
+ if (node) {
+ plist_dict_set_item(request, "Ap,VolumeUUID", plist_copy(node));
+ }
+ node = NULL;
+
+ /* ApECID */
+ node = plist_dict_get_item(parameters, "ApECID");
+ if (node) {
+ plist_dict_set_item(request, "ApECID", plist_copy(node));
+ }
+ node = NULL;
+
+ /* ApChipID */
+ node = plist_dict_get_item(parameters, "ApChipID");
+ if (node) {
+ plist_dict_set_item(request, "ApChipID", plist_copy(node));
+ }
+ node = NULL;
+
+ /* ApBoardID */
+ node = plist_dict_get_item(parameters, "ApBoardID");
+ if (node) {
+ plist_dict_set_item(request, "ApBoardID", plist_copy(node));
+ }
+ node = NULL;
+
+ /* ApSecurityDomain */
+ node = plist_dict_get_item(parameters, "ApSecurityDomain");
+ if (node) {
+ plist_dict_set_item(request, "ApSecurityDomain", plist_copy(node));
+ }
+ node = NULL;
+
+ /* ApNonce */
+ node = plist_dict_get_item(parameters, "ApNonce");
+ if (node) {
+ plist_dict_set_item(request, "ApNonce", plist_copy(node));
+ }
+ node = NULL;
+
+ /* ApSecurityMode */
+ node = plist_dict_get_item(request, "ApSecurityMode");
+ if (!node) {
+ /* copy from parameters if available */
+ node = plist_dict_get_item(parameters, "ApSecurityMode");
+ if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) {
+ error("ERROR: Unable to find required ApSecurityMode in parameters\n");
+ return -1;
+ }
+ plist_dict_set_item(request, "ApSecurityMode", plist_copy(node));
+ node = NULL;
+ }
+
+ node = plist_dict_get_item(request, "ApProductionMode");
+ if (!node) {
+ /* ApProductionMode */
+ node = plist_dict_get_item(parameters, "ApProductionMode");
+ if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) {
+ error("ERROR: Unable to find required ApProductionMode in parameters\n");
+ return -1;
+ }
+ plist_dict_set_item(request, "ApProductionMode", plist_copy(node));
+ node = NULL;
+ }
+
+ return 0;
+}
+
int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity)
{
plist_t node = NULL;
@@ -96,6 +206,12 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity)
plist_dict_set_item(parameters, "UniqueBuildID", plist_copy(node));
node = NULL;
+ /* Ap,OSLongVersion */
+ node = plist_dict_get_item(build_identity, "Ap,OSLongVersion");
+ if (node) {
+ plist_dict_set_item(parameters, "Ap,OSLongVersion", plist_copy(node));
+ }
+
/* ApChipID */
int chip_id = 0;
node = plist_dict_get_item(build_identity, "ApChipID");
@@ -359,6 +475,12 @@ int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters) {
return -1;
}
+ /* Ap,OSLongVersion */
+ node = plist_dict_get_item(parameters, "Ap,OSLongVersion");
+ if (node) {
+ plist_dict_set_item(request, "Ap,OSLongVersion", plist_copy(node));
+ }
+
/* ApNonce */
node = plist_dict_get_item(parameters, "ApNonce");
if (!node || plist_get_node_type(node) != PLIST_DATA) {
@@ -594,7 +716,7 @@ static void tss_entry_apply_restore_request_rules(plist_t tss_entry, plist_t par
}
}
-int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides) {
+int tss_request_add_ap_recovery_tags(plist_t request, plist_t parameters, plist_t overrides) {
/* loop over components from build manifest */
plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
@@ -622,6 +744,120 @@ int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrid
continue;
}
+ // Compared to ac2, not needed for RecoveryOSRootTicket
+ if ((strcmp(key, "SE,UpdatePayload") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "BaseSystem") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "ANS") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,AudioBootChime") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,CIO") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,RestoreCIO") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,RestoreTMU") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,TMU") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,rOSLogo1") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "Ap,rOSLogo2") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "AppleLogo") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "DCP") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "LLB") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RecoveryMode") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreANS") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreDCP") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreDeviceTree") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreKernelCache") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreLogo") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreRamDisk") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "RestoreSEP") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "SEP") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "ftap") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "ftsp") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "iBEC") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "iBSS") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "rfta") == 0)) {
+ free(key);
+ continue;
+ }
+ if ((strcmp(key, "rfts") == 0)) {
+ free(key);
+ continue;
+ }
+
/* FIXME: only used with diagnostics firmware */
if (strcmp(key, "Diags") == 0) {
free(key);
@@ -629,11 +865,114 @@ int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrid
}
if (_plist_dict_get_bool(parameters, "_OnlyFWComponents")) {
+ if (!_plist_dict_get_bool(manifest_entry, "Trusted")) {
+ debug("DEBUG: %s: Skipping '%s' as it is not trusted", __func__, key);
+ continue;
+ }
+
plist_t info_dict = plist_dict_get_item(manifest_entry, "Info");
+ if (!_plist_dict_get_bool(info_dict, "IsFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsSecondaryFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsFUDFirmware")) {
+ debug("DEBUG: %s: Skipping '%s' as it is neither firmware nor secondary nor FUD firmware payload\n", __func__, key);
+ continue;
+ }
+ }
+
+ /* copy this entry */
+ plist_t tss_entry = plist_copy(manifest_entry);
+
+ // ac2 TSS recoveryOSRootTicket needs EPRO and ESEC to be true
+ plist_dict_set_item(tss_entry, "EPRO", plist_new_bool(1));
+ plist_dict_set_item(tss_entry, "ESEC", plist_new_bool(1));
+
+ /* remove obsolete Info node */
+ plist_dict_remove_item(tss_entry, "Info");
+
+ /* handle RestoreRequestRules */
+ plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
+ if (rules) {
+ debug("DEBUG: Applying restore request rules for entry %s\n", key);
+ tss_entry_apply_restore_request_rules(tss_entry, parameters, rules);
+ }
+
+ /* Make sure we have a Digest key for Trusted items even if empty */
+ plist_t node = plist_dict_get_item(manifest_entry, "Trusted");
+ if (node && plist_get_node_type(node) == PLIST_BOOLEAN) {
+ uint8_t trusted;
+ plist_get_bool_val(node, &trusted);
+ if (trusted && !plist_access_path(manifest_entry, 1, "Digest")) {
+ debug("DEBUG: No Digest data, using empty value for entry %s\n", key);
+ plist_dict_set_item(tss_entry, "Digest", plist_new_data(NULL, 0));
+ }
+ }
+
+ /* finally add entry to request */
+ plist_dict_set_item(request, key, tss_entry);
+
+ free(key);
+ }
+ free(iter);
+
+ /* apply overrides */
+ if (overrides) {
+ plist_dict_merge(&request, overrides);
+ }
+
+ return 0;
+}
+
+int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides) {
+ /* loop over components from build manifest */
+ plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
+ if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
+ error("ERROR: Unable to find restore manifest\n");
+ return -1;
+ }
+
+ /* add components to request */
+ char* key = NULL;
+ plist_t manifest_entry = NULL;
+ plist_dict_iter iter = NULL;
+ plist_dict_new_iter(manifest_node, &iter);
+ while (1) {
+ plist_dict_next_item(manifest_node, iter, &key, &manifest_entry);
+ if (key == NULL)
+ break;
+ if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) {
+ error("ERROR: Unable to fetch BuildManifest entry\n");
+ return -1;
+ }
+
+ /* do not populate BaseBandFirmware, only in basebaseband request */
+ if ((strcmp(key, "BasebandFirmware") == 0)) {
+ free(key);
+ continue;
+ }
+
+ // Compared to ac2, not needed
+ if ((strcmp(key, "SE,UpdatePayload") == 0)) {
+ free(key);
+ continue;
+ }
+
+ // Compared to ac2, not needed
+ if ((strcmp(key, "BaseSystem") == 0)) {
+ free(key);
+ continue;
+ }
+
+ /* FIXME: only used with diagnostics firmware */
+ if (strcmp(key, "Diags") == 0) {
+ free(key);
+ continue;
+ }
+
+ if (_plist_dict_get_bool(parameters, "_OnlyFWComponents")) {
if (!_plist_dict_get_bool(manifest_entry, "Trusted")) {
debug("DEBUG: %s: Skipping '%s' as it is not trusted", __func__, key);
continue;
}
+
+ plist_t info_dict = plist_dict_get_item(manifest_entry, "Info");
if (!_plist_dict_get_bool(info_dict, "IsFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsSecondaryFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsFUDFirmware")) {
debug("DEBUG: %s: Skipping '%s' as it is neither firmware nor secondary nor FUD firmware payload\n", __func__, key);
continue;