@@ -496,6 +496,61 @@ Section* VersalAuthenticationContext::CreateCertificate(BootImage& bi, Binary& c
496496 return acSection;
497497}
498498
499+ /* *****************************************************************************/
500+ static uint32_t ComputeWordChecksum (void * firstWordPtr, size_t length)
501+ {
502+ uint32_t checksum = 0 ;
503+ size_t numChecksumedWords = length / sizeof (uint32_t );
504+ for (size_t i = 0 ; i< numChecksumedWords; i++)
505+ {
506+ checksum += ((uint32_t *)firstWordPtr)[i];
507+ }
508+ /* Invert the Checksum value */
509+ checksum ^= 0xFFFFFFFF ;
510+ return checksum;
511+ }
512+
513+ /* *****************************************************************************/
514+ void VersalAuthenticationContext::SetHashinOptionalData (BootImage& bi)
515+ {
516+ uint32_t sectn_size_id = 0 ;
517+ /* Optional Data Header + Optional Data Actual size (32 bit(4Bytes) partition Number + Hash Length in bytes) + Checksum */
518+ uint16_t sectn_length = sizeof (uint32_t ) + (bi.hashTable .size () * (sizeof (uint32_t ) + SHA3_LENGTH_BYTES)) + sizeof (uint32_t );
519+ /* Data ID for Hash block is fixed to 3 */
520+ sectn_size_id = (uint32_t )((sectn_length / 4 ) << 16 ) | DATA_ID_PARTITION_HASHES;
521+
522+ memcpy (bi.iht_optional_data + (bi.copied_iht_optional_data_length / 4 ), §n_size_id, sizeof (uint32_t ));
523+ bi.copied_iht_optional_data_length += sizeof (uint32_t );
524+ for (size_t i = 0 ; i < bi.hashTable .size (); i++)
525+ {
526+ uint32_t partition_num = bi.hashTable [i].first ;
527+ memcpy (bi.iht_optional_data + (bi.copied_iht_optional_data_length / 4 ), &partition_num, sizeof (uint32_t ));
528+ bi.copied_iht_optional_data_length += sizeof (uint32_t );
529+ memcpy (bi.iht_optional_data + (bi.copied_iht_optional_data_length / 4 ), bi.hashTable [i].second , SHA3_LENGTH_BYTES);
530+ bi.copied_iht_optional_data_length += SHA3_LENGTH_BYTES;
531+ }
532+
533+ uint32_t checksum = ComputeWordChecksum (bi.iht_optional_data + ((bi.copied_iht_optional_data_length - sectn_length + sizeof (uint32_t )) / 4 ),
534+ sectn_length - sizeof (uint32_t ));
535+ memcpy (bi.iht_optional_data + (bi.copied_iht_optional_data_length / 4 ), &checksum, sizeof (uint32_t ));
536+ bi.copied_iht_optional_data_length += sizeof (uint32_t );
537+
538+ if (bi.copied_iht_optional_data_length != 0 )
539+ {
540+ uint32_t padLength = (bi.copied_iht_optional_data_length % 64 != 0 ) ? 64 - (bi.copied_iht_optional_data_length % 64 ) : 0 ;
541+ if (bi.copied_iht_optional_data_length + padLength != bi.iht_optional_data_length )
542+ {
543+ LOG_ERROR (" Optional Data Length doen't match the calculated length" );
544+ }
545+ }
546+
547+ memcpy (bi.imageHeaderTable ->section ->Data + sizeof (VersalImageHeaderTableStructure) + (bi.copied_iht_optional_data_length - sectn_length),
548+ bi.iht_optional_data + (bi.copied_iht_optional_data_length - sectn_length) / 4 , sectn_length);
549+ // bi.copied_iht_optional_data_length += sectn_length;
550+ LOG_TRACE (" Partition Hash processed to optional data" );
551+
552+ }
553+
499554/* *****************************************************************************/
500555void VersalAuthenticationContext::Link (BootImage& bi, std::list<Section*> sections, AuthenticationCertificate* cert)
501556{
@@ -507,25 +562,56 @@ void VersalAuthenticationContext::Link(BootImage& bi, std::list<Section*> sectio
507562 }
508563
509564 /* Copy meta header Signature when headers */
510- if (sections.front ()->Name == " Headers" )
511- {
512- CopyIHTSignature (bi, cert->section ->Data + AC_BH_SIGN_OFFSET);
513- }
565+ /* With authentication optimization */
566+ if (bi.options .IsAuthOptimizationEnabled ()){
567+ if (sections.front ()->Name == " Headers" )
568+ {
569+ CopyPartitionSignature (bi, sections, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, cert->section );
570+ SetHashinOptionalData (bi);
571+ CopyIHTSignature (bi, cert->section ->Data + AC_BH_SIGN_OFFSET);
572+ }
514573
515- if (presignFile == " " )
516- {
517- CopyPartitionSignature (bi, sections, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, cert->section );
574+ if (presignFile == " " )
575+ {
576+ if (sections.front ()->Name != " Headers" ){
577+ CopyPartitionSignature (bi, sections, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, cert->section );
578+ }
579+ }
580+ else
581+ {
582+ int index = acIndex;
583+ if (cert->section ->index != 0 )
584+ {
585+ index = cert->section ->index ;
586+ }
587+ GetPresign (presignFile, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, index);
588+ acIndex++;
589+ }
518590 }
591+ /* Normal flow -- Without authentication optimization */
519592 else
520593 {
521- int index = acIndex;
522- if (cert->section ->index != 0 )
594+ if (sections.front ()->Name == " Headers" )
523595 {
524- index = cert->section ->index ;
596+ CopyIHTSignature (bi, cert->section ->Data + AC_BH_SIGN_OFFSET) ;
525597 }
526- GetPresign (presignFile, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, index);
527- acIndex++;
528- }
598+
599+ if (presignFile == " " )
600+ {
601+ CopyPartitionSignature (bi, sections, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, cert->section );
602+ }
603+ else
604+ {
605+ int index = acIndex;
606+ if (cert->section ->index != 0 )
607+ {
608+ index = cert->section ->index ;
609+ }
610+ GetPresign (presignFile, cert->section ->Data + AC_PARTITION_SIGN_OFFSET, index);
611+ acIndex++;
612+ }
613+ }
614+
529615}
530616
531617/* *****************************************************************************/
@@ -906,21 +992,30 @@ void VersalAuthenticationContext::CopyPartitionSignature(BootImage& bi, std::lis
906992 {
907993 hashSecLen = (*section)->firstChunkSize + hashLength;
908994 }
995+
909996 /* Update with AC and then Partition */
910- uint8_t *partitionAc = new uint8_t [hashSecLen + (acSection->Length - signatureLength)];
997+ int signSecLength = acSection->Length - signatureLength;
998+ /* Remove the IHT signature length from sign section in case of auth optimization*/
999+ if (bi.options .IsAuthOptimizationEnabled () && (*section)->Name == " Headers" )
1000+ {
1001+ signSecLength -= signatureLength;
1002+ (*section)->partitionNum = 0x00 ;
1003+ }
1004+
1005+ uint8_t *partitionAc = new uint8_t [hashSecLen + signSecLength];
9111006
9121007 /* Update with authentication certificate except the last 256 bytes - which is the partition signature that we are calculating now.
9131008 Once calculated, the partition signature will sit there */
914- memcpy (partitionAc, acSection->Data , acSection-> Length - signatureLength );
1009+ memcpy (partitionAc, acSection->Data , signSecLength );
9151010
9161011 /* Update with Partition */
917- memcpy (partitionAc + acSection-> Length - signatureLength , (*section)->Data , hashSecLen);
1012+ memcpy (partitionAc + signSecLength , (*section)->Data , hashSecLen);
9181013
9191014 /* Calculate the final hash */
920- Versalcrypto_hash (shaHash, partitionAc, hashSecLen + (acSection-> Length - signatureLength) , !((*section)->isBootloader && !bi.options .IsVersalNetSeries ()));
1015+ Versalcrypto_hash (shaHash, partitionAc, hashSecLen + signSecLength , !((*section)->isBootloader && !bi.options .IsVersalNetSeries ()));
9211016 LOG_TRACE (" Hash of %s (LE):" , acSection->Name .c_str ());
9221017 LOG_DUMP_BYTES (shaHash, hashLength);
923- if (bi.options .IsAuthOptimizationEnabled () && ((*section)-> Name != " Headers " ) && !((*section)->isBootloader ))
1018+ if (bi.options .IsAuthOptimizationEnabled () && !((*section)->isBootloader ))
9241019 {
9251020 uint8_t * hash = new uint8_t [hashLength];
9261021 bi.hashTable .push_back (std::pair<uint32_t , uint8_t *>((*section)->partitionNum , hash));
0 commit comments