2424
2525#include "common.h"
2626#include "img4.h"
27+ #include "tss.h"
2728
2829#define ASN1_PRIVATE 0xc0
2930#define ASN1_PRIMITIVE_TAG 0x1f
@@ -201,7 +202,7 @@ static void asn1_write_element(unsigned char **p, unsigned int *length, unsigned
201202 }
202203 } break ;
203204 default :
204- fprintf (stderr , "ERROR: %s: type %02x is not implemented" , __func__ , type );
205+ fprintf (stderr , "ERROR: %s: type %02x is not implemented\n " , __func__ , type );
205206 return ;
206207 }
207208}
@@ -393,7 +394,38 @@ static const char *_img4_get_component_tag(const char *compname)
393394 return NULL ;
394395}
395396
396- 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 )
397+ static void hexdump (char * data , int length )
398+ {
399+ int i ;
400+ int j ;
401+ unsigned char c ;
402+
403+ for (i = 0 ; i < length ; i += 16 ) {
404+ fprintf (stderr , "%04x: " , i );
405+ for (j = 0 ; j < 16 ; j ++ ) {
406+ if (i + j >= length ) {
407+ fprintf (stderr , " " );
408+ continue ;
409+ }
410+ fprintf (stderr , "%02x " , * (data + i + j ) & 0xff );
411+ }
412+ fprintf (stderr , " | " );
413+ for (j = 0 ; j < 16 ; j ++ ) {
414+ if (i + j >= length )
415+ break ;
416+ c = * (data + i + j );
417+ if ((c < 32 ) || (c > 127 )) {
418+ fprintf (stderr , "." );
419+ continue ;
420+ }
421+ fprintf (stderr , "%c" , c );
422+ }
423+ fprintf (stderr , "\n" );
424+ }
425+ fprintf (stderr , "\n" );
426+ }
427+
428+ 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 )
397429{
398430 unsigned char * magic_header = NULL ;
399431 unsigned int magic_header_size = 0 ;
@@ -404,8 +436,15 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
404436 unsigned int content_size ;
405437 unsigned char * outbuf ;
406438 unsigned char * p ;
439+ unsigned char * blob = NULL ;
440+ unsigned int blob_size = 0 ;
407441
408- if (!component_name || !component_data || component_size == 0 || !blob || blob_size == 0 || !img4_data || !img4_size ) {
442+ if (!component_name || !component_data || component_size == 0 || !tss_response || !img4_data || !img4_size ) {
443+ return -1 ;
444+ }
445+
446+ if (tss_response_get_ap_img4_ticket (tss_response , & blob , & blob_size ) != 0 ) {
447+ error ("ERROR: %s: Failed to get ApImg4Ticket from TSS response\n" , __func__ );
409448 return -1 ;
410449 }
411450
@@ -435,13 +474,152 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
435474 }
436475 }
437476
477+ // check if we have a *-TBM entry for the given component
478+ unsigned char * additional_data = NULL ;
479+ unsigned int additional_size = 0 ;
480+ char * tbm_key = malloc (strlen (component_name ) + 5 );
481+ sprintf (tbm_key , "%s-TBM" , component_name );
482+ plist_t tbm_dict = plist_dict_get_item (tss_response , tbm_key );
483+ free (tbm_key );
484+ if (tbm_dict ) {
485+ plist_t dt = plist_dict_get_item (tbm_dict , "ucon" );
486+ if (!dt ) {
487+ error ("ERROR: %s: Missing ucon node in %s-TBM dictionary\n" , __func__ , component_name );
488+ return -1 ;
489+ }
490+ uint64_t ucon_size = 0 ;
491+ const char * ucon_data = plist_get_data_ptr (dt , & ucon_size );
492+ if (!ucon_data ) {
493+ error ("ERROR: %s: Missing ucon data in %s-TBM dictionary\n" , __func__ , component_name );
494+ return -1 ;
495+ }
496+ dt = plist_dict_get_item (tbm_dict , "ucer" );
497+ if (!dt ) {
498+ error ("ERROR: %s: Missing ucer data node in %s-TBM dictionary\n" , __func__ , component_name );
499+ return -1 ;
500+ }
501+ uint64_t ucer_size = 0 ;
502+ const char * ucer_data = plist_get_data_ptr (dt , & ucer_size );
503+ if (!ucer_data ) {
504+ error ("ERROR: %s: Missing ucer data in %s-TBM dictionary\n" , __func__ , component_name );
505+ return -1 ;
506+ }
507+
508+ unsigned char * im4rset = (unsigned char * )malloc (16 + 8 + 8 + ucon_size + 16 + 8 + 8 + ucer_size + 16 );
509+ unsigned char * p_im4rset = im4rset ;
510+ unsigned int im4rlen = 0 ;
511+
512+ // ----------- ucon ------------
513+ // write priv ucon element
514+ asn1_write_priv_element (& p_im4rset , & im4rlen , * (uint32_t * )"nocu" );
515+
516+ // write ucon IA5STRING and ucon data
517+ unsigned char ucon_seq [16 ];
518+ unsigned char * p_ucon_seq = & ucon_seq [0 ];
519+ unsigned int ucon_seq_hdr_len = 0 ;
520+ asn1_write_element (& p_ucon_seq , & ucon_seq_hdr_len , ASN1_IA5_STRING , (void * )"ucon" , -1 );
521+ asn1_write_element_header (ASN1_OCTET_STRING , ucon_size , & p_ucon_seq , & ucon_seq_hdr_len );
522+
523+ // write ucon sequence
524+ unsigned char elem_seq [8 ];
525+ unsigned char * p = & elem_seq [0 ];
526+ unsigned int seq_hdr_len = 0 ;
527+ asn1_write_element_header (ASN1_SEQUENCE | ASN1_CONSTRUCTED , ucon_seq_hdr_len + ucon_size , & p , & seq_hdr_len );
528+
529+ // add size to priv ucon element
530+ asn1_write_size (ucon_seq_hdr_len + ucon_size + seq_hdr_len , & p_im4rset , & im4rlen );
531+
532+ // put it together
533+ memcpy (p_im4rset , elem_seq , seq_hdr_len );
534+ p_im4rset += seq_hdr_len ;
535+ im4rlen += seq_hdr_len ;
536+ memcpy (p_im4rset , ucon_seq , ucon_seq_hdr_len );
537+ p_im4rset += ucon_seq_hdr_len ;
538+ im4rlen += ucon_seq_hdr_len ;
539+ memcpy (p_im4rset , ucon_data , ucon_size );
540+ p_im4rset += ucon_size ;
541+ im4rlen += ucon_size ;
542+
543+ // ----------- ucer ------------
544+ // write priv ucer element
545+ asn1_write_priv_element (& p_im4rset , & im4rlen , * (uint32_t * )"recu" );
546+
547+ // write ucon IA5STRING and ucer data
548+ unsigned char ucer_seq [16 ];
549+ unsigned char * p_ucer_seq = & ucer_seq [0 ];
550+ unsigned int ucer_seq_hdr_len = 0 ;
551+ asn1_write_element (& p_ucer_seq , & ucer_seq_hdr_len , ASN1_IA5_STRING , (void * )"ucer" , -1 );
552+ asn1_write_element_header (ASN1_OCTET_STRING , ucer_size , & p_ucer_seq , & ucer_seq_hdr_len );
553+
554+ p = & elem_seq [0 ];
555+ seq_hdr_len = 0 ;
556+ asn1_write_element_header (ASN1_SEQUENCE | ASN1_CONSTRUCTED , ucer_seq_hdr_len + ucer_size , & p , & seq_hdr_len );
557+
558+ // add size to priv ucer element
559+ asn1_write_size (ucer_seq_hdr_len + ucer_size + seq_hdr_len , & p_im4rset , & im4rlen );
560+
561+ // put it together
562+ memcpy (p_im4rset , elem_seq , seq_hdr_len );
563+ p_im4rset += seq_hdr_len ;
564+ im4rlen += seq_hdr_len ;
565+ memcpy (p_im4rset , ucer_seq , ucer_seq_hdr_len );
566+ p_im4rset += ucer_seq_hdr_len ;
567+ im4rlen += ucer_seq_hdr_len ;
568+ memcpy (p_im4rset , ucer_data , ucer_size );
569+ p_im4rset += ucer_size ;
570+ im4rlen += ucer_size ;
571+
572+ // now construct IM4R
573+
574+ /* write inner set */
575+ unsigned char inner_set_ [8 ];
576+ unsigned char * inner_set = & inner_set_ [0 ];
577+ unsigned int inner_set_len = 0 ;
578+ asn1_write_element_header (ASN1_SET | ASN1_CONSTRUCTED , im4rlen , & inner_set , & inner_set_len );
579+
580+ /* write header values */
581+ unsigned char hdrdata_ [16 ];
582+ unsigned char * hdrdata = & hdrdata_ [0 ];
583+ unsigned int hdrdata_len = 0 ;
584+ asn1_write_element (& hdrdata , & hdrdata_len , ASN1_IA5_STRING , (void * )"IM4R" , -1 );
585+
586+ /* write sequence now that we know the entire size */
587+ unsigned char seq_ [8 ];
588+ unsigned char * seq = & seq_ [0 ];
589+ unsigned int seq_len = 0 ;
590+ asn1_write_element_header (ASN1_SEQUENCE | ASN1_CONSTRUCTED , im4rlen + inner_set_len + hdrdata_len , & seq , & seq_len );
591+
592+ /* write outer cont[1] */
593+ unsigned char cont_ [8 ];
594+ unsigned char * cont = & cont_ [0 ];
595+ unsigned int cont_len = 0 ;
596+ asn1_write_element_header (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 , im4rlen + inner_set_len + hdrdata_len + seq_len , & cont , & cont_len );
597+
598+ // now put everything together
599+ additional_data = malloc (im4rlen + inner_set_len + hdrdata_len + seq_len + cont_len );
600+ p = additional_data ;
601+ memcpy (p , cont_ , cont_len );
602+ p += cont_len ;
603+ memcpy (p , seq_ , seq_len );
604+ p += seq_len ;
605+ memcpy (p , hdrdata_ , hdrdata_len );
606+ p += hdrdata_len ;
607+ memcpy (p , inner_set_ , inner_set_len );
608+ p += inner_set_len ;
609+ memcpy (p , im4rset , im4rlen );
610+ p += im4rlen ;
611+ additional_size = (unsigned int )(p - additional_data );
612+
613+ free (im4rset );
614+ }
615+
438616 // create element header for the "IMG4" magic
439617 asn1_create_element_header (ASN1_IA5_STRING , IMG4_MAGIC_SIZE , & magic_header , & magic_header_size );
440618 // create element header for the blob (ApImg4Ticket)
441619 asn1_create_element_header (ASN1_CONTEXT_SPECIFIC |ASN1_CONSTRUCTED , blob_size , & blob_header , & blob_header_size );
442620
443621 // calculate the size for the final IMG4 file (asn1 sequence)
444- content_size = magic_header_size + IMG4_MAGIC_SIZE + component_size + blob_header_size + blob_size ;
622+ content_size = magic_header_size + IMG4_MAGIC_SIZE + component_size + blob_header_size + blob_size + additional_size ;
445623
446624 // create element header for the final IMG4 asn1 blob
447625 asn1_create_element_header (ASN1_SEQUENCE |ASN1_CONSTRUCTED , content_size , & img4header , & img4header_size );
@@ -457,6 +635,7 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
457635 if (img4header ) {
458636 free (img4header );
459637 }
638+ free (additional_data );
460639 error ("ERROR: out of memory when personalizing IMG4 component %s\n" , component_name );
461640 return -1 ;
462641 }
@@ -475,6 +654,10 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
475654 p += blob_header_size ;
476655 memcpy (p , blob , blob_size );
477656 p += blob_size ;
657+ if (additional_size ) {
658+ memcpy (p , additional_data , additional_size );
659+ p += additional_size ;
660+ }
478661
479662 * img4_data = outbuf ;
480663 * img4_size = (p - outbuf );
@@ -488,6 +671,7 @@ int img4_stitch_component(const char* component_name, const unsigned char* compo
488671 if (img4header ) {
489672 free (img4header );
490673 }
674+ free (additional_data );
491675
492676 return 0 ;
493677}
0 commit comments