summaryrefslogtreecommitdiffstats
path: root/src/img4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/img4.c')
-rw-r--r--src/img4.c218
1 files changed, 190 insertions, 28 deletions
diff --git a/src/img4.c b/src/img4.c
index 4988293..56b0496 100644
--- a/src/img4.c
+++ b/src/img4.c
@@ -24,6 +24,7 @@
#include "common.h"
#include "img4.h"
+#include "tss.h"
#define ASN1_PRIVATE 0xc0
#define ASN1_PRIMITIVE_TAG 0x1f
@@ -201,7 +202,7 @@ static void asn1_write_element(unsigned char **p, unsigned int *length, unsigned
}
} break;
default:
- fprintf(stderr, "ERROR: %s: type %02x is not implemented", __func__, type);
+ fprintf(stderr, "ERROR: %s: type %02x is not implemented\n", __func__, type);
return;
}
}
@@ -275,28 +276,37 @@ static const char *_img4_get_component_tag(const char *compname)
{ "ACIBT", "acib" },
{ "ACIBTLPEM", "lpbt" },
{ "ACIWIFI", "aciw" },
- { "Alamo", "almo" },
{ "ANE", "anef" },
{ "ANS", "ansf" },
{ "AOP", "aopf" },
+ { "AVE", "avef" },
+ { "Alamo", "almo" },
+ { "Ap,ANE1", "ane1" },
+ { "Ap,ANE2", "ane2" },
+ { "Ap,ANE3", "ane3" },
{ "Ap,AudioAccessibilityBootChime", "auac" },
{ "Ap,AudioBootChime", "aubt" },
{ "Ap,AudioPowerAttachChime", "aupr" },
+ { "Ap,BootabilityBrainTrustCache", "trbb" },
{ "Ap,CIO", "ciof" },
{ "Ap,HapticAssets", "hpas" },
{ "Ap,LocalBoot", "lobo" },
{ "Ap,LocalPolicy", "lpol" },
{ "Ap,NextStageIM4MHash", "nsih" },
{ "Ap,RecoveryOSPolicyNonceHash", "ronh" },
+ { "Ap,RestoreANE1", "ran1" },
+ { "Ap,RestoreANE2", "ran2" },
+ { "Ap,RestoreANE3", "ran3" },
{ "Ap,RestoreCIO", "rcio" },
{ "Ap,RestoreTMU", "rtmu" },
{ "Ap,Scorpius", "scpf" },
{ "Ap,SystemVolumeCanonicalMetadata", "msys" },
{ "Ap,TMU", "tmuf" },
{ "Ap,VolumeUUID", "vuid" },
+ { "Ap,rOSLogo1", "rlg1" },
+ { "Ap,rOSLogo2", "rlg2" },
{ "AppleLogo", "logo" },
{ "AudioCodecFirmware", "acfw" },
- { "AVE", "avef" },
{ "BatteryCharging", "glyC" },
{ "BatteryCharging0", "chg0" },
{ "BatteryCharging1", "chg1" },
@@ -305,28 +315,22 @@ static const char *_img4_get_component_tag(const char *compname)
{ "BatteryLow1", "bat1" },
{ "BatteryPlugin", "glyP" },
{ "CFELoader", "cfel" },
- { "Dali", "dali" },
+ { "CrownFirmware", "crwn" },
{ "DCP", "dcpf" },
+ { "Dali", "dali" },
{ "DeviceTree", "dtre" },
{ "Diags", "diag" },
{ "EngineeringTrustCache", "dtrs" },
{ "ExtDCP", "edcp" },
- { "ftap", "ftap" },
- { "ftsp", "ftsp" },
{ "GFX", "gfxf" },
{ "Hamm", "hamf" },
{ "Homer", "homr" },
- { "iBEC", "ibec" },
- { "iBoot", "ibot" },
- { "iBootData", "ibdt" },
- { "iBootTest", "itst" },
- { "iBSS", "ibss" },
- { "InputDevice", "ipdf" },
{ "ISP", "ispf" },
+ { "InputDevice", "ipdf" },
{ "KernelCache", "krnl" },
+ { "LLB", "illb" },
{ "LeapHaptics", "lphp" },
{ "Liquid", "liqd" },
- { "LLB", "illb" },
{ "LoadableTrustCache", "ltrs" },
{ "LowPowerWallet0", "lpw0" },
{ "LowPowerWallet1", "lpw1" },
@@ -337,12 +341,13 @@ static const char *_img4_get_component_tag(const char *compname)
{ "NeedService", "nsrv" },
{ "OS", "OS\0\0" },
{ "OSRamdisk", "osrd" },
- { "PersonalizedDMG", "pdmg" },
{ "PEHammer", "hmmr" },
{ "PERTOS", "pert" },
{ "PHLEET", "phlt" },
{ "PMP", "pmpf" },
+ { "PersonalizedDMG", "pdmg" },
{ "RBM", "rmbt" },
+ { "RTP", "rtpf" },
{ "Rap,SoftwareBinaryDsp1", "sbd1" },
{ "Rap,RTKitOS", "rkos" },
{ "Rap,RestoreRTKitOS", "rrko" },
@@ -353,12 +358,10 @@ static const char *_img4_get_component_tag(const char *compname)
{ "RestoreExtDCP", "recp" },
{ "RestoreKernelCache", "rkrn" },
{ "RestoreLogo", "rlgo" },
+ { "RestoreRTP", "rrtp" },
{ "RestoreRamDisk", "rdsk" },
{ "RestoreSEP", "rsep" },
{ "RestoreTrustCache", "rtsc" },
- { "rfta", "rfta" },
- { "rfts", "rfts" },
- { "RTP", "rtpf" },
{ "SCE", "scef" },
{ "SCE1Firmware", "sc1f" },
{ "SEP", "sepi" },
@@ -367,6 +370,16 @@ static const char *_img4_get_component_tag(const char *compname)
{ "SystemLocker", "lckr" },
{ "SystemVolume", "isys" },
{ "WCHFirmwareUpdater", "wchf" },
+ { "ftap", "ftap" },
+ { "ftsp", "ftsp" },
+ { "iBEC", "ibec" },
+ { "iBSS", "ibss" },
+ { "iBoot", "ibot" },
+ { "iBootData", "ibdt" },
+ { "iBootDataStage1", "ibd1" },
+ { "iBootTest", "itst" },
+ { "rfta", "rfta" },
+ { "rfts", "rfts" },
{ NULL, NULL }
};
int i = 0;
@@ -381,7 +394,7 @@ static const char *_img4_get_component_tag(const char *compname)
return NULL;
}
-int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, const unsigned char* blob, unsigned int blob_size, unsigned char** img4_data, unsigned int *img4_size)
+int img4_stitch_component(const char* component_name, const unsigned char* component_data, unsigned int component_size, plist_t tss_response, unsigned char** img4_data, unsigned int *img4_size)
{
unsigned char* magic_header = NULL;
unsigned int magic_header_size = 0;
@@ -392,8 +405,15 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
unsigned int content_size;
unsigned char* outbuf;
unsigned char* p;
+ unsigned char* blob = NULL;
+ unsigned int blob_size = 0;
+
+ if (!component_name || !component_data || component_size == 0 || !tss_response || !img4_data || !img4_size) {
+ return -1;
+ }
- if (!component_name || !component_data || component_size == 0 || !blob || blob_size == 0 || !img4_data || !img4_size) {
+ if (tss_response_get_ap_img4_ticket(tss_response, &blob, &blob_size) != 0) {
+ error("ERROR: %s: Failed to get ApImg4Ticket from TSS response\n", __func__);
return -1;
}
@@ -423,13 +443,152 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
}
}
+ // check if we have a *-TBM entry for the given component
+ unsigned char *additional_data = NULL;
+ unsigned int additional_size = 0;
+ char *tbm_key = malloc(strlen(component_name) + 5);
+ sprintf(tbm_key, "%s-TBM", component_name);
+ plist_t tbm_dict = plist_dict_get_item(tss_response, tbm_key);
+ free(tbm_key);
+ if (tbm_dict) {
+ plist_t dt = plist_dict_get_item(tbm_dict, "ucon");
+ if (!dt) {
+ error("ERROR: %s: Missing ucon node in %s-TBM dictionary\n", __func__, component_name);
+ return -1;
+ }
+ uint64_t ucon_size = 0;
+ const char* ucon_data = plist_get_data_ptr(dt, &ucon_size);
+ if (!ucon_data) {
+ error("ERROR: %s: Missing ucon data in %s-TBM dictionary\n", __func__, component_name);
+ return -1;
+ }
+ dt = plist_dict_get_item(tbm_dict, "ucer");
+ if (!dt) {
+ error("ERROR: %s: Missing ucer data node in %s-TBM dictionary\n", __func__, component_name);
+ return -1;
+ }
+ uint64_t ucer_size = 0;
+ const char* ucer_data = plist_get_data_ptr(dt, &ucer_size);
+ if (!ucer_data) {
+ error("ERROR: %s: Missing ucer data in %s-TBM dictionary\n", __func__, component_name);
+ return -1;
+ }
+
+ unsigned char *im4rset = (unsigned char*)malloc(16 + 8 + 8 + ucon_size + 16 + 8 + 8 + ucer_size + 16);
+ unsigned char *p_im4rset = im4rset;
+ unsigned int im4rlen = 0;
+
+ // ----------- ucon ------------
+ // write priv ucon element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"nocu");
+
+ // write ucon IA5STRING and ucon data
+ unsigned char ucon_seq[16];
+ unsigned char *p_ucon_seq = &ucon_seq[0];
+ unsigned int ucon_seq_hdr_len = 0;
+ asn1_write_element(&p_ucon_seq, &ucon_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucon", -1);
+ asn1_write_element_header(ASN1_OCTET_STRING, ucon_size, &p_ucon_seq, &ucon_seq_hdr_len);
+
+ // write ucon sequence
+ unsigned char elem_seq[8];
+ unsigned char *p = &elem_seq[0];
+ unsigned int seq_hdr_len = 0;
+ asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, ucon_seq_hdr_len + ucon_size, &p, &seq_hdr_len);
+
+ // add size to priv ucon element
+ asn1_write_size(ucon_seq_hdr_len + ucon_size + seq_hdr_len, &p_im4rset, &im4rlen);
+
+ // put it together
+ memcpy(p_im4rset, elem_seq, seq_hdr_len);
+ p_im4rset += seq_hdr_len;
+ im4rlen += seq_hdr_len;
+ memcpy(p_im4rset, ucon_seq, ucon_seq_hdr_len);
+ p_im4rset += ucon_seq_hdr_len;
+ im4rlen += ucon_seq_hdr_len;
+ memcpy(p_im4rset, ucon_data, ucon_size);
+ p_im4rset += ucon_size;
+ im4rlen += ucon_size;
+
+ // ----------- ucer ------------
+ // write priv ucer element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"recu");
+
+ // write ucon IA5STRING and ucer data
+ unsigned char ucer_seq[16];
+ unsigned char *p_ucer_seq = &ucer_seq[0];
+ unsigned int ucer_seq_hdr_len = 0;
+ asn1_write_element(&p_ucer_seq, &ucer_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucer", -1);
+ asn1_write_element_header(ASN1_OCTET_STRING, ucer_size, &p_ucer_seq, &ucer_seq_hdr_len);
+
+ p = &elem_seq[0];
+ seq_hdr_len = 0;
+ asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, ucer_seq_hdr_len + ucer_size, &p, &seq_hdr_len);
+
+ // add size to priv ucer element
+ asn1_write_size(ucer_seq_hdr_len + ucer_size + seq_hdr_len, &p_im4rset, &im4rlen);
+
+ // put it together
+ memcpy(p_im4rset, elem_seq, seq_hdr_len);
+ p_im4rset += seq_hdr_len;
+ im4rlen += seq_hdr_len;
+ memcpy(p_im4rset, ucer_seq, ucer_seq_hdr_len);
+ p_im4rset += ucer_seq_hdr_len;
+ im4rlen += ucer_seq_hdr_len;
+ memcpy(p_im4rset, ucer_data, ucer_size);
+ p_im4rset += ucer_size;
+ im4rlen += ucer_size;
+
+ // now construct IM4R
+
+ /* write inner set */
+ unsigned char inner_set_[8];
+ unsigned char *inner_set = &inner_set_[0];
+ unsigned int inner_set_len = 0;
+ asn1_write_element_header(ASN1_SET | ASN1_CONSTRUCTED, im4rlen, &inner_set, &inner_set_len);
+
+ /* write header values */
+ unsigned char hdrdata_[16];
+ unsigned char *hdrdata = &hdrdata_[0];
+ unsigned int hdrdata_len = 0;
+ asn1_write_element(&hdrdata, &hdrdata_len, ASN1_IA5_STRING, (void*)"IM4R", -1);
+
+ /* write sequence now that we know the entire size */
+ unsigned char seq_[8];
+ unsigned char *seq = &seq_[0];
+ unsigned int seq_len = 0;
+ asn1_write_element_header(ASN1_SEQUENCE | ASN1_CONSTRUCTED, im4rlen + inner_set_len + hdrdata_len, &seq, &seq_len);
+
+ /* write outer cont[1] */
+ unsigned char cont_[8];
+ unsigned char *cont = &cont_[0];
+ unsigned int cont_len = 0;
+ asn1_write_element_header(ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, im4rlen + inner_set_len + hdrdata_len + seq_len, &cont, &cont_len);
+
+ // now put everything together
+ additional_data = malloc(im4rlen + inner_set_len + hdrdata_len + seq_len + cont_len);
+ p = additional_data;
+ memcpy(p, cont_, cont_len);
+ p += cont_len;
+ memcpy(p, seq_, seq_len);
+ p += seq_len;
+ memcpy(p, hdrdata_, hdrdata_len);
+ p += hdrdata_len;
+ memcpy(p, inner_set_, inner_set_len);
+ p += inner_set_len;
+ memcpy(p, im4rset, im4rlen);
+ p += im4rlen;
+ additional_size = (unsigned int)(p - additional_data);
+
+ free(im4rset);
+ }
+
// create element header for the "IMG4" magic
asn1_create_element_header(ASN1_IA5_STRING, IMG4_MAGIC_SIZE, &magic_header, &magic_header_size);
// create element header for the blob (ApImg4Ticket)
asn1_create_element_header(ASN1_CONTEXT_SPECIFIC|ASN1_CONSTRUCTED, blob_size, &blob_header, &blob_header_size);
// calculate the size for the final IMG4 file (asn1 sequence)
- content_size = magic_header_size + IMG4_MAGIC_SIZE + component_size + blob_header_size + blob_size;
+ content_size = magic_header_size + IMG4_MAGIC_SIZE + component_size + blob_header_size + blob_size + additional_size;
// create element header for the final IMG4 asn1 blob
asn1_create_element_header(ASN1_SEQUENCE|ASN1_CONSTRUCTED, content_size, &img4header, &img4header_size);
@@ -445,6 +604,7 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
if (img4header) {
free(img4header);
}
+ free(additional_data);
error("ERROR: out of memory when personalizing IMG4 component %s\n", component_name);
return -1;
}
@@ -463,6 +623,10 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
p += blob_header_size;
memcpy(p, blob, blob_size);
p += blob_size;
+ if (additional_size) {
+ memcpy(p, additional_data, additional_size);
+ p += additional_size;
+ }
*img4_data = outbuf;
*img4_size = (p - outbuf);
@@ -476,6 +640,7 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
if (img4header) {
free(img4header);
}
+ free(additional_data);
return 0;
}
@@ -627,8 +792,6 @@ int img4_create_local_manifest(plist_t request, plist_t build_identity, plist_t*
unsigned int length = 0;
uint64_t uintval = 0;
unsigned int boolval = 0;
- char *strval = NULL;
- plist_t node = NULL;
unsigned char tmp_[1024];
unsigned char *tmp = &tmp_[0];
@@ -681,13 +844,12 @@ int img4_create_local_manifest(plist_t request, plist_t build_identity, plist_t*
comp = _img4_get_component_tag(key);
}
if (!comp) {
- error("ERROR: %s: Unhandled component '%s' - can't create manifest\n", __func__, key);
- free(iter);
- free(buf);
- return -1;
+ debug("DEBUG: %s: Unhandled component '%s'\n", __func__, key);
+ _manifest_write_component(&p, &length, key, val);
+ } else {
+ debug("DEBUG: found component %s (%s)\n", comp, key);
+ _manifest_write_component(&p, &length, comp, val);
}
- debug("DEBUG: found component %s (%s)\n", comp, key);
- _manifest_write_component(&p, &length, comp, val);
}
free(key);
} while (val);