@@ -42,13 +42,8 @@ STATIC EFI_GUID gEfiShimLockGuid =
4242EFI_GUID gEfiMicrosoftGuid =
4343 { 0x77FA9ABD , 0x0359 , 0x4D32 , { 0xBD , 0x60 , 0x28 , 0xF4 , 0xE7 , 0x8F , 0x78 , 0x4B } };
4444
45- /* Attributes for the "key" types we support */
46- STATIC struct {
47- CHAR8 * DisplayName ;
48- CHAR16 * OptionName ;
49- CHAR16 * VariableName ;
50- EFI_GUID * VariableGuid ;
51- } KeyInfo [MAX_TYPES ] = {
45+ /* Populate the key type attributes */
46+ MOSBY_KEY_INFO KeyInfo [MAX_TYPES ] = {
5247 [PK ] = {
5348 .DisplayName = "PK: " ,
5449 .OptionName = L"-pk" ,
@@ -229,7 +224,7 @@ EFI_STATUS EFIAPI efi_main(
229224 UINT16 * SystemSSPV = NULL ;
230225 UINT32 SystemSBatVer = 0 , InstallSBatVer = 0 ;
231226 INTN Argc , Type , Sel , LastEntry ;
232- MOSBY_CRED Cred = { 0 };
227+ MOSBY_CRED PkCred = { 0 }, DbCred = { 0 };
233228 CHAR8 DbSubject [80 ], PkSubject [80 ], * SBat = NULL , * SBatLine = NULL ;
234229 CHAR16 * * Argv = NULL , * * ArgvCopy , MosbyKeyPath [MAX_PATH ];
235230 MOSBY_LIST List ;
@@ -414,6 +409,17 @@ EFI_STATUS EFIAPI efi_main(
414409 }
415410
416411process_binaries :
412+
413+ /* Generate the credentials, which we use both to sign the authvars as well as PK */
414+ Status = gRT -> GetTime (& Time , NULL );
415+ if (EFI_ERROR (Status ))
416+ ReportErrorAndExit (L"Failed to get time - Aborting\n" );
417+ AsciiSPrint (PkSubject , sizeof (PkSubject ), "Mosby Generated PK [%04d.%02d.%02d]" ,
418+ Time .Year , Time .Month , Time .Day );
419+ Status = GenerateCredentials (PkSubject , & PkCred );
420+ if (EFI_ERROR (Status ))
421+ ReportErrorAndExit (L"Failed to generate signing credentials - Aborting\n" );
422+
417423 /* Process binaries that have been provided to the application */
418424 for (i = 0 ; i < List .Size ; i ++ ) {
419425 if (List .Entry [i ].Variable .Data != NULL )
@@ -435,7 +441,7 @@ EFI_STATUS EFIAPI efi_main(
435441 List .Entry [i ].Attrs = UEFI_VAR_NV_BS ;
436442 break ;
437443 default :
438- Status = PopulateAuthVar (& List .Entry [i ]);
444+ Status = PopulateAuthVar (& List .Entry [i ], & PkCred );
439445 if (EFI_ERROR (Status ))
440446 ReportErrorAndExit (L"Failed to create variable - Aborting\n" );
441447 break ;
@@ -492,58 +498,44 @@ EFI_STATUS EFIAPI efi_main(
492498 i = List .Size ;
493499 RecallPrint (L"Generating Secure Boot signing credentials...\n" );
494500 List .Entry [i ].Type = DB ;
495- Status = gRT -> GetTime (& Time , NULL );
496- if (EFI_ERROR (Status ))
497- ReportErrorAndExit (L"Failed to get time - Aborting\n" );
498501 AsciiSPrint (DbSubject , sizeof (DbSubject ), "%a [%04d.%02d.%02d]" ,
499502 MOSBY_CRED_NAME , Time .Year , Time .Month , Time .Day );
500503 List .Entry [i ].Description = DbSubject ;
501- Status = GenerateCredentials (DbSubject , & Cred );
504+ Status = GenerateCredentials (DbSubject , & DbCred );
502505 if (EFI_ERROR (Status ))
503506 goto exit ;
504- Status = CertToAuthVar (Cred .Cert , & List .Entry [i ].Variable , FALSE);
505- if (EFI_ERROR (Status )) {
506- FreeCredentials (& Cred );
507+ Status = CertToAuthVar (DbCred .Cert , & List .Entry [i ].Variable , FALSE);
508+ if (EFI_ERROR (Status ))
507509 goto exit ;
508- }
509- List .Entry [i ].Attrs = UEFI_VAR_NV_BS_RT_AT_AP ;
510- Status = SaveCredentials (WIDEN (MOSBY_CRED_NAME ), & Cred );
510+ Status = SaveCredentials (WIDEN (MOSBY_CRED_NAME ), & DbCred );
511511 if (EFI_ERROR (Status ))
512512 goto exit ;
513513 RecallPrint (L"Saved Secure Boot signing credentials as '%a'\n" , MOSBY_CRED_NAME );
514- FreeCredentials (& Cred );
514+
515+ List .Entry [i ].Attrs = UEFI_VAR_NV_BS_RT_AT_AP ;
516+ Status = SignAuthVar (KeyInfo [DB ].VariableName , KeyInfo [DB ].VariableGuid ,
517+ List .Entry [i ].Attrs , & List .Entry [i ].Variable , & PkCred );
518+ if (EFI_ERROR (Status ))
519+ ReportErrorAndExit (L"Failed to sign DB\n" );
515520 List .Size ++ ;
516521 }
517522
518- /* Generate a keyless PK cert if none was specified */
523+ /* Set up the PK if none was specified */
519524 LastEntry = RemoveDuplicates (PK , & List );
520525 if (LastEntry < 0 ) {
521526 if (List .Size >= MOSBY_MAX_LIST_SIZE )
522527 Abort (EFI_OUT_OF_RESOURCES , L"List size is too small\n" );
523528 RecallPrint (L"Generating PK certificate...\n" );
524529 i = List .Size ;
525530 List .Entry [i ].Type = PK ;
526- if (!GenDBCred ) {
527- Status = gRT -> GetTime (& Time , NULL );
528- if (EFI_ERROR (Status ))
529- ReportErrorAndExit (L"Failed to get time - Aborting\n" );
530- }
531- AsciiSPrint (PkSubject , sizeof (PkSubject ), "Mosby Generated PK [%04d.%02d.%02d]" ,
532- Time .Year , Time .Month , Time .Day );
533531 List .Entry [i ].Description = PkSubject ;
534- Status = GenerateCredentials ( PkSubject , & Cred );
532+ Status = CertToAuthVar ( PkCred . Cert , & List . Entry [ i ]. Variable , FALSE );
535533 if (EFI_ERROR (Status ))
536534 goto exit ;
537- Status = CertToAuthVar (Cred .Cert , & List .Entry [i ].Variable , FALSE);
538- if (EFI_ERROR (Status )) {
539- FreeCredentials (& Cred );
540- goto exit ;
541- }
542535 // PK must be signed
543536 List .Entry [i ].Attrs = UEFI_VAR_NV_BS_RT_AT ;
544- Status = SignToAuthVar (KeyInfo [PK ].VariableName , KeyInfo [PK ].VariableGuid ,
545- List .Entry [i ].Attrs , & List .Entry [i ].Variable , & Cred );
546- FreeCredentials (& Cred );
537+ Status = SignAuthVar (KeyInfo [PK ].VariableName , KeyInfo [PK ].VariableGuid ,
538+ List .Entry [i ].Attrs , & List .Entry [i ].Variable , & PkCred );
547539 if (EFI_ERROR (Status )) {
548540 SafeFree (List .Entry [i ].Variable .Data );
549541 goto exit ;
@@ -554,9 +546,10 @@ EFI_STATUS EFIAPI efi_main(
554546#if defined(_M_X64 ) || defined(__x86_64__ ) || defined(_M_IX86 ) || defined(__i386__ )
555547 /*
556548 * There appears to be a whole sway of AMI UEFI firmwares with a rather unfortunate bug,
557- * that prevents appending to an existing KEK store. Which means that, on the affected
549+ * that prevents appending to an existing KEK store (or even creating the initial KEK
550+ * variable if it is done with the append flag set). Which means that, on the affected
558551 * systems, if we try to write more than one KEK, using multiple SetVariable() calls,
559- * only the first call succeeds and all subsequent ones fail with EFI_INVALID_PARAMETER.
552+ * only the first can succeed and all subsequent ones fail with EFI_INVALID_PARAMETER.
560553 * To work around this and since any unsigned KEK we processed above should already have
561554 * been converted to an ESL (embedded in an EFI_VARIABLE_AUTHENTICATION_2 struct), we
562555 * concatenate all these ESLs into a single array, which can then be written through a
@@ -581,8 +574,9 @@ EFI_STATUS EFIAPI efi_main(
581574 RecallPrint (L"Adding '%s' to Merged KEK List\n" , List .Entry [i ].Path );
582575 /* Get the ESL data from EFI_VARIABLE_AUTHENTICATION_2 (at .AuthInfo.CertData) */
583576 Esl [EslIndex ++ ] = (EFI_SIGNATURE_LIST * )& ((UINT8 * )List .Entry [i ].Variable .Data )[
577+ ((List .Entry [i ].Variable .Data -> AuthInfo .CertData [2 ] << 8 ) | List .Entry [i ].Variable .Data -> AuthInfo .CertData [3 ]) +
584578 OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2 , AuthInfo ) +
585- OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID , CertData )];
579+ OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID , CertData ) + 4 ];
586580 /* Remove the individual KEK from our installation list, since it will be merged */
587581 List .Entry [i ].Flags |= NO_INSTALL ;
588582 }
@@ -604,7 +598,7 @@ EFI_STATUS EFIAPI efi_main(
604598 List .Entry [List .Size ].Attrs = UEFI_VAR_NV_BS_RT_AT ;
605599 List .Entry [List .Size ].Description = "Merged KEK List" ;
606600 List .Entry [List .Size ].Path = L"Merged KEK List" ;
607- Status = PopulateAuthVar (& List .Entry [List .Size ]);
601+ Status = PopulateAuthVar (& List .Entry [List .Size ], & PkCred );
608602 if (EFI_ERROR (Status ))
609603 ReportErrorAndExit (L"Failed to create merged KEK variable - Aborting\n" );
610604 List .Size ++ ;
@@ -644,6 +638,8 @@ EFI_STATUS EFIAPI efi_main(
644638exit :
645639 for (i = 0 ; i < List .Size ; i ++ )
646640 FreePool (List .Entry [i ].Variable .Data );
641+ FreeCredentials (& DbCred );
642+ FreeCredentials (& PkCred );
647643 FreePool (Argv );
648644 RecallPrintFree ();
649645 CloseLogger ();
0 commit comments