summaryrefslogtreecommitdiffstats
path: root/src/img4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/img4.c')
-rw-r--r--src/img4.c193
1 files changed, 131 insertions, 62 deletions
diff --git a/src/img4.c b/src/img4.c
index c010ce4..e9d4cca 100644
--- a/src/img4.c
+++ b/src/img4.c
@@ -26,6 +26,7 @@
#include "common.h"
#include "img4.h"
+#include "endianness.h"
#define ASN1_PRIVATE 0xc0
#define ASN1_PRIMITIVE_TAG 0x1f
@@ -395,7 +396,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, plist_t tss_response, 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 parameters, plist_t tss_response, unsigned char** img4_data, unsigned int *img4_size)
{
unsigned char* magic_header = NULL;
unsigned int magic_header_size = 0;
@@ -459,14 +460,17 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
snprintf(tbm_key, strlen(component_name)+5, "%s-TBM", component_name);
plist_t tbm_dict = plist_dict_get_item(tss_response, tbm_key);
free(tbm_key);
+ uint64_t ucon_size = 0;
+ const char* ucon_data = NULL;
+ uint64_t ucer_size = 0;
+ const char* ucer_data = NULL;
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);
+ 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;
@@ -476,76 +480,141 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
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);
+ 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;
}
+ }
+
+ int nonce_slot_required = plist_dict_get_bool(parameters, "RequiresNonceSlot") && (!strcmp(component_name, "SEP") || !strcmp(component_name, "SepStage1") || !strcmp(component_name, "LLB"));
- unsigned char *im4rset = (unsigned char*)malloc(16 + 8 + 8 + ucon_size + 16 + 8 + 8 + ucer_size + 16);
+ if (ucon_data || ucer_data || nonce_slot_required) {
+ size_t im4r_size = 16;
+ if (ucon_data) {
+ im4r_size += 8 + 8 + ucon_size + 16;
+ }
+ if (ucer_data) {
+ im4r_size += 8 + 8 + ucer_size + 16;
+ }
+ if (nonce_slot_required) {
+ im4r_size += 16;
+ }
+ unsigned char *im4rset = (unsigned char*)malloc(im4r_size);
unsigned char *p_im4rset = im4rset;
unsigned int im4rlen = 0;
+ // ----------- anid/snid -------
+ if (nonce_slot_required) {
+ const char* tag_name = NULL;
+ uint64_t tag_value = 0;
+ if (!strcmp(component_name, "SEP") || !strcmp(component_name, "SepStage1")) {
+ tag_name = "snid";
+ tag_value = 2;
+ if (plist_dict_get_item(parameters, "SepNonceSlotID")) {
+ tag_value = plist_dict_get_uint(parameters, "SepNonceSlotID");
+ }
+ } else {
+ tag_name = "anid";
+ tag_value = 0;
+ if (plist_dict_get_item(parameters, "ApNonceSlotID")) {
+ tag_value = plist_dict_get_uint(parameters, "ApNonceSlotID");
+ }
+ }
+ // write priv anid/snid element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, __bswap_32(*(uint32_t*)tag_name));
+ // write anid/snid IA5STRING and anid/snid value
+ unsigned char inner_seq[16];
+ unsigned char *p_inner_seq = &inner_seq[0];
+ unsigned int inner_seq_hdr_len = 0;
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_IA5_STRING, (void*)tag_name, -1);
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_INTEGER, (void*)&tag_value, -1);
+
+ // write anid/snid 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, inner_seq_hdr_len, &p, &seq_hdr_len);
+
+ // add size to priv anid/snid element
+ asn1_write_size(inner_seq_hdr_len + 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, inner_seq, inner_seq_hdr_len);
+ p_im4rset += inner_seq_hdr_len;
+ im4rlen += inner_seq_hdr_len;
+ }
+
// ----------- 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;
+ if (ucon_data) {
+ // write priv ucon element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"nocu");
+
+ // write ucon IA5STRING and ucon data header
+ unsigned char inner_seq[16];
+ unsigned char *p_inner_seq = &inner_seq[0];
+ unsigned int inner_seq_hdr_len = 0;
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucon", -1);
+ asn1_write_element_header(ASN1_OCTET_STRING, ucon_size, &p_inner_seq, &inner_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, inner_seq_hdr_len + ucon_size, &p, &seq_hdr_len);
+
+ // add size to priv ucon element
+ asn1_write_size(inner_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, inner_seq, inner_seq_hdr_len);
+ p_im4rset += inner_seq_hdr_len;
+ im4rlen += inner_seq_hdr_len;
+ // write ucon data
+ 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;
+ if (ucer_data) {
+ // write priv ucer element
+ asn1_write_priv_element(&p_im4rset, &im4rlen, *(uint32_t*)"recu");
+
+ // write ucer IA5STRING and ucer data header
+ unsigned char inner_seq[16];
+ unsigned char *p_inner_seq = &inner_seq[0];
+ unsigned int inner_seq_hdr_len = 0;
+ asn1_write_element(&p_inner_seq, &inner_seq_hdr_len, ASN1_IA5_STRING, (void*)"ucer", -1);
+ asn1_write_element_header(ASN1_OCTET_STRING, ucer_size, &p_inner_seq, &inner_seq_hdr_len);
+
+ // write ucer 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, inner_seq_hdr_len + ucer_size, &p, &seq_hdr_len);
+
+ // add size to priv ucer element
+ asn1_write_size(inner_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, inner_seq, inner_seq_hdr_len);
+ p_im4rset += inner_seq_hdr_len;
+ im4rlen += inner_seq_hdr_len;
+ // write ucer data
+ memcpy(p_im4rset, ucer_data, ucer_size);
+ p_im4rset += ucer_size;
+ im4rlen += ucer_size;
+ }
// now construct IM4R