Skip to content

Commit 3a0f879

Browse files
2024.1 Updates
1. Support for Authentication Optimization 2. Minor Bug Fixes Signed-off-by: Ramya Darapuneni <[email protected]>
1 parent a36cc52 commit 3a0f879

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4320
-3316
lines changed

authentication-versal.cpp

Lines changed: 113 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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), &sectn_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
/******************************************************************************/
500555
void 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));

authentication-versal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ class VersalAuthenticationContext : public AuthenticationContext
284284
void SetKeyLength(Authentication::Type type);
285285
AuthenticationAlgorithm* GetAuthenticationAlgorithm(Authentication::Type type);
286286
uint32_t GetCertificateSize();
287+
void SetHashinOptionalData(BootImage& bi);
287288

288289
private:
289290
void CopybHSignature(BootImage& bi, uint8_t* ptr);

authentication-zynqmp.cpp

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,14 @@ Section* ZynqMpAuthenticationContext::CreateCertificate(BootImage& bi, Binary& c
362362
/* Secondary key is must for authenticating */
363363
if (!secondaryKey->Loaded)
364364
{
365-
LOG_ERROR("Authentication Error !!!\n Secondary key must be specified in BIF file for %s", dataSection->Name.c_str());
365+
if (acFile != "")
366+
{
367+
// ok
368+
}
369+
else
370+
{
371+
LOG_ERROR("Authentication Error !!!\n Secondary key must be specified in BIF file for %s", dataSection->Name.c_str());
372+
}
366373
}
367374

368375
if (!secondaryKey->isSecret)
@@ -371,6 +378,10 @@ Section* ZynqMpAuthenticationContext::CreateCertificate(BootImage& bi, Binary& c
371378
{
372379
// ok
373380
}
381+
else if (acFile != "")
382+
{
383+
// ok
384+
}
374385
else if (bi.options.GetNonBootingFlag() && (dataSection->Name.find("ImageHeaderTable") != std::string::npos))
375386
{
376387
// ok
@@ -404,6 +415,10 @@ Section* ZynqMpAuthenticationContext::CreateCertificate(BootImage& bi, Binary& c
404415
{
405416
LOG_WARNING("Either PSK or spksignature is needed to authenticate bootimage or generate partition hashes. Because they are not provided, the bootimage and partition hashes will not be usable. However SPK hash and bootheader hash files generated can be used for offline signing.");
406417
}
418+
else if (acFile != "")
419+
{
420+
// ok
421+
}
407422
else
408423
{
409424
LOG_ERROR("Authentication Error !!!\n Either PSK or SPK signature file must be specified in BIF file.");
@@ -429,32 +444,38 @@ Section* ZynqMpAuthenticationContext::CreateCertificate(BootImage& bi, Binary& c
429444
LOG_ERROR("Authentication Error !!!");
430445
}
431446
memset(authCert, 0, certSize);
432-
433-
uint32_t acHdr = AUTH_HDR_ZYNQMP;
434-
acHdr |= ppkSelect << AC_HDR_PPK_SELECT_BIT_SHIFT;
435-
acHdr |= spkSelect << AC_HDR_SPK_SELECT_BIT_SHIFT;
436-
acHdr |= ((bi.GetAuthHashAlgo()) ? 0 : 1) << AC_HDR_SHA_2_3_BIT_SHIFT;
437-
438-
WriteLittleEndian32(&authCert->acHeader, acHdr);
439-
WriteLittleEndian32(&authCert->spkId, spkIdentification);
440-
441-
if (udfFile != "")
447+
if (acFile != "")
442448
{
443-
LoadUdfData(udfFile, udf_data);
444-
RearrangeEndianess(udf_data, sizeof(udf_data));
445-
memcpy(authCert->acUdf, udf_data, UDF_DATA_SIZE);
449+
// ok
446450
}
451+
else
452+
{
453+
uint32_t acHdr = AUTH_HDR_ZYNQMP;
454+
acHdr |= ppkSelect << AC_HDR_PPK_SELECT_BIT_SHIFT;
455+
acHdr |= spkSelect << AC_HDR_SPK_SELECT_BIT_SHIFT;
456+
acHdr |= ((bi.GetAuthHashAlgo()) ? 0 : 1) << AC_HDR_SHA_2_3_BIT_SHIFT;
457+
458+
WriteLittleEndian32(&authCert->acHeader, acHdr);
459+
WriteLittleEndian32(&authCert->spkId, spkIdentification);
447460

448-
primaryKey->Export(&authCert->acPpk);
449-
RearrangeEndianess(authCert->acPpk.N, sizeof(authCert->acPpk.N));
450-
RearrangeEndianess(authCert->acPpk.N_extension, sizeof(authCert->acPpk.N_extension));
451-
RearrangeEndianess(authCert->acPpk.E, sizeof(authCert->acPpk.E));
452-
secondaryKey->Export(&authCert->acSpk);
453-
RearrangeEndianess(authCert->acSpk.N, sizeof(authCert->acSpk.N));
454-
RearrangeEndianess(authCert->acSpk.N_extension, sizeof(authCert->acSpk.N_extension));
455-
RearrangeEndianess(authCert->acSpk.E, sizeof(authCert->acSpk.E));
461+
if (udfFile != "")
462+
{
463+
LoadUdfData(udfFile, udf_data);
464+
RearrangeEndianess(udf_data, sizeof(udf_data));
465+
memcpy(authCert->acUdf, udf_data, UDF_DATA_SIZE);
466+
}
456467

457-
CopySPKSignature(&authCert->acSpkSignature);
468+
primaryKey->Export(&authCert->acPpk);
469+
RearrangeEndianess(authCert->acPpk.N, sizeof(authCert->acPpk.N));
470+
RearrangeEndianess(authCert->acPpk.N_extension, sizeof(authCert->acPpk.N_extension));
471+
RearrangeEndianess(authCert->acPpk.E, sizeof(authCert->acPpk.E));
472+
secondaryKey->Export(&authCert->acSpk);
473+
RearrangeEndianess(authCert->acSpk.N, sizeof(authCert->acSpk.N));
474+
RearrangeEndianess(authCert->acSpk.N_extension, sizeof(authCert->acSpk.N_extension));
475+
RearrangeEndianess(authCert->acSpk.E, sizeof(authCert->acSpk.E));
476+
477+
CopySPKSignature(&authCert->acSpkSignature);
478+
}
458479
certIndex++;
459480
return acSection;
460481
}
@@ -466,7 +487,18 @@ void ZynqMpAuthenticationContext::Link(BootImage& bi, std::list<Section*> sectio
466487
uint8_t* signatureBlock = (uint8_t*)&authCert->acPartitionSignature;
467488
CopyBHSignature(bi, &authCert->acBhSignature);
468489

469-
if (presignFile == "")
490+
if (acFile != "")
491+
{
492+
/* If the parition AC file present */
493+
int index = acIndex;
494+
if (cert->section->index != 0)
495+
{
496+
index = cert->section->index;
497+
}
498+
GetAC(acFile, cert->section->Data, index);
499+
acIndex++;
500+
}
501+
else if (presignFile == "")
470502
{
471503
/* If the parition is not presigned / presign file not present */
472504
std::list<Section*>::iterator section = sections.begin();
@@ -527,6 +559,10 @@ void ZynqMpAuthenticationContext::CopyBHSignature(BootImage& bi, ACSignature4096
527559
warningGiven = true;
528560
}
529561
}
562+
else if (acFile != "")
563+
{
564+
// ok
565+
}
530566
else
531567
{
532568
LOG_ERROR("Authentication Error !!!\n Either SSK or BH signature file must be specified in the BIF file.");

authentication.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,19 @@ bool AuthenticationContext::zynpmpVerEs1 = false;
4444
***************************************************** F U N C T I O N S ***
4545
-------------------------------------------------------------------------------
4646
*/
47-
void AuthenticationContext::SetPresignFile(const std::string& filename)
47+
48+
/******************************************************************************/
49+
void AuthenticationContext::SetPresignFile(const std::string& filename)
4850
{
4951
presignFile = filename;
5052
}
5153

54+
/******************************************************************************/
55+
void AuthenticationContext::SetACFile(const std::string& filename)
56+
{
57+
acFile = filename;
58+
}
59+
5260
/******************************************************************************/
5361
void AuthenticationContext::SetUdfFile(const std::string& filename)
5462
{
@@ -270,6 +278,54 @@ void AuthenticationContext::GetPresign(const std::string& presignFilename, uint8
270278
}
271279
}
272280

281+
/******************************************************************************/
282+
void AuthenticationContext::GetAC(const std::string& acFilename, uint8_t* ac, uint32_t index)
283+
{
284+
std::string filename(acFilename);
285+
std::string baseFile = StringUtils::BaseName(filename);
286+
287+
if (index != 0)
288+
{
289+
size_t x = filename.find(".0.");
290+
if (x == std::string::npos)
291+
{
292+
LOG_ERROR("AC file %s does not have partition index (*.0.*)", baseFile.c_str());
293+
}
294+
// nudge the '0' to index number
295+
std::string sindex = std::to_string(index);
296+
filename.replace(x + 1, 1, sindex);
297+
}
298+
299+
LOG_TRACE("Reading AC from - %s", filename.c_str());
300+
FILE* filePtr;
301+
filePtr = fopen(filename.c_str(), "rb");
302+
if (filePtr)
303+
{
304+
fseek(filePtr, 0, SEEK_END);
305+
long size = ftell(filePtr);
306+
fclose(filePtr);
307+
if (size == GetCertificateSize())
308+
{
309+
// read binary
310+
filePtr = fopen(filename.c_str(), "rb");
311+
long read_size = fread(ac, 1, GetCertificateSize(), filePtr);
312+
if (read_size != GetCertificateSize())
313+
{
314+
LOG_ERROR("Authentication Error !!!\n AC file %s should be of %d bytes", baseFile.c_str(), GetCertificateSize());
315+
}
316+
fclose(filePtr);
317+
}
318+
else
319+
{
320+
LOG_ERROR("Authentication Error !!!\n AC file %s should be of %d bytes", baseFile.c_str(), GetCertificateSize());
321+
}
322+
}
323+
else
324+
{
325+
LOG_ERROR("Failure opening AC file - %s", baseFile.c_str());
326+
}
327+
}
328+
273329
/******************************************************************************/
274330
void AuthenticationContext::LoadUdfData(const std::string& udfFilename, uint8_t* signature)
275331
{

0 commit comments

Comments
 (0)