3 #include <Library/BaseCryptLib.h>
4 #include <openssl/x509.h>
5 #include "console_control.h"
8 #include "PasswordCrypt.h"
12 #include "variables.h"
13 #include "simple_file.h"
14 #include "efiauthenticated.h"
16 #define PASSWORD_MAX 256
17 #define PASSWORD_MIN 1
18 #define SB_PASSWORD_LEN 16
20 #define NAME_LINE_MAX 70
23 #define SHIM_VENDOR L"Shim"
26 #define EFI_VARIABLE_APPEND_WRITE 0x00000040
28 EFI_GUID SHIM_LOCK_GUID
= { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
30 #define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
31 #define HASH_STRING L"Select a file to trust:\n\n"
35 INTN (* callback
)(void *data
, void *data2
, void *data3
);
46 } __attribute__ ((packed
)) MokListNode
;
51 CHAR16 Password
[SB_PASSWORD_LEN
];
52 } __attribute__ ((packed
)) MokSBvar
;
54 static EFI_STATUS
get_sha1sum (void *Data
, int DataSize
, UINT8
*hash
)
60 ctxsize
= Sha1GetContextSize();
61 ctx
= AllocatePool(ctxsize
);
64 console_notify(L
"Unable to allocate memory for hash context");
65 return EFI_OUT_OF_RESOURCES
;
69 console_notify(L
"Unable to initialise hash");
70 status
= EFI_OUT_OF_RESOURCES
;
74 if (!(Sha1Update(ctx
, Data
, DataSize
))) {
75 console_notify(L
"Unable to generate hash");
76 status
= EFI_OUT_OF_RESOURCES
;
80 if (!(Sha1Final(ctx
, hash
))) {
81 console_notify(L
"Unable to finalise hash");
82 status
= EFI_OUT_OF_RESOURCES
;
91 static UINT32
count_keys(void *Data
, UINTN DataSize
)
93 EFI_SIGNATURE_LIST
*CertList
= Data
;
94 EFI_GUID CertType
= X509_GUID
;
95 EFI_GUID HashType
= EFI_CERT_SHA256_GUID
;
96 UINTN dbsize
= DataSize
;
99 while ((dbsize
> 0) && (dbsize
>= CertList
->SignatureListSize
)) {
100 if ((CompareGuid (&CertList
->SignatureType
, &CertType
) != 0) &&
101 (CompareGuid (&CertList
->SignatureType
, &HashType
) != 0)) {
102 console_notify(L
"Doesn't look like a key or hash");
103 dbsize
-= CertList
->SignatureListSize
;
104 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
105 CertList
->SignatureListSize
);
109 if ((CompareGuid (&CertList
->SignatureType
, &CertType
) != 0) &&
110 (CertList
->SignatureSize
!= 48)) {
111 console_notify(L
"Doesn't look like a valid hash");
112 dbsize
-= CertList
->SignatureListSize
;
113 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
114 CertList
->SignatureListSize
);
119 dbsize
-= CertList
->SignatureListSize
;
120 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
121 CertList
->SignatureListSize
);
127 static MokListNode
*build_mok_list(UINT32 num
, void *Data
, UINTN DataSize
) {
129 EFI_SIGNATURE_LIST
*CertList
= Data
;
130 EFI_SIGNATURE_DATA
*Cert
;
131 EFI_GUID CertType
= X509_GUID
;
132 EFI_GUID HashType
= EFI_CERT_SHA256_GUID
;
133 UINTN dbsize
= DataSize
;
136 list
= AllocatePool(sizeof(MokListNode
) * num
);
139 console_notify(L
"Unable to allocate MOK list");
143 while ((dbsize
> 0) && (dbsize
>= CertList
->SignatureListSize
)) {
144 if ((CompareGuid (&CertList
->SignatureType
, &CertType
) != 0) &&
145 (CompareGuid (&CertList
->SignatureType
, &HashType
) != 0)) {
146 dbsize
-= CertList
->SignatureListSize
;
147 CertList
= (EFI_SIGNATURE_LIST
*)((UINT8
*) CertList
+
148 CertList
->SignatureListSize
);
152 if ((CompareGuid (&CertList
->SignatureType
, &HashType
) == 0) &&
153 (CertList
->SignatureSize
!= 48)) {
154 dbsize
-= CertList
->SignatureListSize
;
155 CertList
= (EFI_SIGNATURE_LIST
*)((UINT8
*) CertList
+
156 CertList
->SignatureListSize
);
160 Cert
= (EFI_SIGNATURE_DATA
*) (((UINT8
*) CertList
) +
161 sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
163 list
[count
].MokSize
= CertList
->SignatureSize
- sizeof(EFI_GUID
);
164 list
[count
].Mok
= (void *)Cert
->SignatureData
;
165 list
[count
].Type
= CertList
->SignatureType
;
168 dbsize
-= CertList
->SignatureListSize
;
169 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
170 CertList
->SignatureListSize
);
181 static NidName nidname
[] = {
182 {NID_commonName
, L
"CN"},
183 {NID_organizationName
, L
"O"},
184 {NID_countryName
, L
"C"},
185 {NID_stateOrProvinceName
, L
"ST"},
186 {NID_localityName
, L
"L"},
190 static CHAR16
* get_x509_name (X509_NAME
*X509Name
)
192 CHAR16 name
[NAME_LINE_MAX
+1];
193 CHAR16 part
[NAME_LINE_MAX
+1];
194 char str
[NAME_LINE_MAX
];
195 int i
, len
, rest
, first
;
198 rest
= NAME_LINE_MAX
;
200 for (i
= 0; nidname
[i
].name
!= NULL
; i
++) {
202 len
= X509_NAME_get_text_by_NID (X509Name
, nidname
[i
].nid
,
208 add
= len
+ (int)StrLen(nidname
[i
].name
) + 1;
210 add
= len
+ (int)StrLen(nidname
[i
].name
) + 3;
216 SPrint(part
, NAME_LINE_MAX
* sizeof(CHAR16
), L
"%s=%a",
217 nidname
[i
].name
, str
);
219 SPrint(part
, NAME_LINE_MAX
* sizeof(CHAR16
), L
", %s=%a",
220 nidname
[i
].name
, str
);
227 if (rest
>= 0 && rest
< NAME_LINE_MAX
)
228 return PoolPrint(L
"%s", name
);
233 static CHAR16
* get_x509_time (ASN1_TIME
*time
)
235 BIO
*bio
= BIO_new (BIO_s_mem());
239 ASN1_TIME_print (bio
, time
);
240 len
= BIO_read(bio
, str
, 29);
246 return PoolPrint(L
"%a", str
);
249 static void show_x509_info (X509
*X509Cert
, UINT8
*hash
)
251 ASN1_INTEGER
*serial
;
253 unsigned char hexbuf
[30];
256 CHAR16
*issuer
= NULL
;
257 CHAR16
*subject
= NULL
;
259 CHAR16
*until
= NULL
;
260 POOL_PRINT hash_string1
;
261 POOL_PRINT hash_string2
;
262 POOL_PRINT serial_string
;
267 ZeroMem(&hash_string1
, sizeof(hash_string1
));
268 ZeroMem(&hash_string2
, sizeof(hash_string2
));
269 ZeroMem(&serial_string
, sizeof(serial_string
));
271 serial
= X509_get_serialNumber(X509Cert
);
274 bnser
= ASN1_INTEGER_to_BN(serial
, NULL
);
275 n
= BN_bn2bin(bnser
, hexbuf
);
276 for (i
= 0; i
< n
; i
++) {
277 CatPrint(&serial_string
, L
"%02x:", hexbuf
[i
]);
281 if (serial_string
.str
)
284 X509Name
= X509_get_issuer_name(X509Cert
);
286 issuer
= get_x509_name(X509Name
);
291 X509Name
= X509_get_subject_name(X509Cert
);
293 subject
= get_x509_name(X509Name
);
298 time
= X509_get_notBefore(X509Cert
);
300 from
= get_x509_time(time
);
305 time
= X509_get_notAfter(X509Cert
);
307 until
= get_x509_time(time
);
313 CatPrint(&hash_string1
, L
"%02x ", hash
[i
]);
314 for (i
=10; i
<20; i
++)
315 CatPrint(&hash_string2
, L
"%02x ", hash
[i
]);
317 if (hash_string1
.str
)
320 if (hash_string2
.str
)
327 text
= AllocateZeroPool(sizeof(CHAR16
*) * (fields
*3 + 1));
328 if (serial_string
.str
) {
329 text
[i
++] = StrDuplicate(L
"[Serial Number]");
330 text
[i
++] = serial_string
.str
;
331 text
[i
++] = StrDuplicate(L
"");
334 text
[i
++] = StrDuplicate(L
"[Issuer]");
336 text
[i
++] = StrDuplicate(L
"");
339 text
[i
++] = StrDuplicate(L
"[Subject]");
341 text
[i
++] = StrDuplicate(L
"");
344 text
[i
++] = StrDuplicate(L
"[Valid Not Before]");
346 text
[i
++] = StrDuplicate(L
"");
349 text
[i
++] = StrDuplicate(L
"[Valid Not After]");
351 text
[i
++] = StrDuplicate(L
"");
353 if (hash_string1
.str
) {
354 text
[i
++] = StrDuplicate(L
"[Fingerprint]");
355 text
[i
++] = hash_string1
.str
;
357 if (hash_string2
.str
) {
358 text
[i
++] = hash_string2
.str
;
359 text
[i
++] = StrDuplicate(L
"");
363 console_print_box(text
, -1);
365 for (i
=0; text
[i
] != NULL
; i
++)
371 static void show_efi_hash (UINT8
*hash
)
374 POOL_PRINT hash_string1
;
375 POOL_PRINT hash_string2
;
378 ZeroMem(&hash_string1
, sizeof(hash_string1
));
379 ZeroMem(&hash_string2
, sizeof(hash_string2
));
381 text
[0] = L
"SHA256 hash";
385 CatPrint(&hash_string1
, L
"%02x ", hash
[i
]);
386 for (i
=16; i
<32; i
++)
387 CatPrint(&hash_string2
, L
"%02x ", hash
[i
]);
389 text
[2] = hash_string1
.str
;
390 text
[3] = hash_string2
.str
;
393 console_print_box(text
, -1);
395 if (hash_string1
.str
)
396 FreePool(hash_string1
.str
);
398 if (hash_string2
.str
)
399 FreePool(hash_string2
.str
);
402 static void show_mok_info (void *Mok
, UINTN MokSize
)
404 EFI_STATUS efi_status
;
405 UINT8 hash
[SHA1_DIGEST_SIZE
];
408 if (!Mok
|| MokSize
== 0)
411 if (MokSize
!= SHA256_DIGEST_SIZE
) {
412 efi_status
= get_sha1sum(Mok
, MokSize
, hash
);
414 if (efi_status
!= EFI_SUCCESS
) {
415 console_notify(L
"Failed to compute MOK fingerprint");
419 if (X509ConstructCertificate(Mok
, MokSize
,
420 (UINT8
**) &X509Cert
) && X509Cert
!= NULL
) {
421 show_x509_info(X509Cert
, hash
);
424 console_notify(L
"Not a valid X509 certificate");
432 static EFI_STATUS
list_keys (void *KeyList
, UINTN KeyListSize
, CHAR16
*title
)
435 MokListNode
*keys
= NULL
;
437 CHAR16
**menu_strings
;
440 if (KeyListSize
< (sizeof(EFI_SIGNATURE_LIST
) +
441 sizeof(EFI_SIGNATURE_DATA
))) {
442 console_notify(L
"No MOK keys found");
446 MokNum
= count_keys(KeyList
, KeyListSize
);
447 keys
= build_mok_list(MokNum
, KeyList
, KeyListSize
);
450 console_notify(L
"Failed to construct key list");
454 menu_strings
= AllocateZeroPool(sizeof(CHAR16
*) * (MokNum
+ 2));
457 return EFI_OUT_OF_RESOURCES
;
459 for (i
=0; i
<MokNum
; i
++) {
460 menu_strings
[i
] = PoolPrint(L
"View key %d", i
);
462 menu_strings
[i
] = StrDuplicate(L
"Continue");
464 menu_strings
[i
+1] = NULL
;
466 while (key_num
< MokNum
) {
467 key_num
= console_select((CHAR16
*[]){ title
, NULL
},
472 else if (key_num
< MokNum
)
473 show_mok_info(keys
[key_num
].Mok
, keys
[key_num
].MokSize
);
476 for (i
=0; menu_strings
[i
] != NULL
; i
++)
477 FreePool(menu_strings
[i
]);
479 FreePool(menu_strings
);
486 static UINT8
get_line (UINT32
*length
, CHAR16
*line
, UINT32 line_max
, UINT8 show
)
492 key
= console_get_keystroke();
494 if ((count
>= line_max
&&
495 key
.UnicodeChar
!= CHAR_BACKSPACE
) ||
496 key
.UnicodeChar
== CHAR_NULL
||
497 key
.UnicodeChar
== CHAR_TAB
||
498 key
.UnicodeChar
== CHAR_LINEFEED
||
499 key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
503 if (count
== 0 && key
.UnicodeChar
== CHAR_BACKSPACE
) {
505 } else if (key
.UnicodeChar
== CHAR_BACKSPACE
) {
509 line
[--count
] = '\0';
514 Print(L
"%c", key
.UnicodeChar
);
517 line
[count
++] = key
.UnicodeChar
;
518 } while (key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
526 static EFI_STATUS
compute_pw_hash (void *Data
, UINTN DataSize
, UINT8
*password
,
527 UINT32 pw_length
, UINT8
*hash
)
530 unsigned int ctxsize
;
533 ctxsize
= Sha256GetContextSize();
534 ctx
= AllocatePool(ctxsize
);
537 console_notify(L
"Unable to allocate memory for hash context");
538 return EFI_OUT_OF_RESOURCES
;
541 if (!Sha256Init(ctx
)) {
542 console_notify(L
"Unable to initialise hash");
543 status
= EFI_OUT_OF_RESOURCES
;
547 if (Data
&& DataSize
) {
548 if (!(Sha256Update(ctx
, Data
, DataSize
))) {
549 console_notify(L
"Unable to generate hash");
550 status
= EFI_OUT_OF_RESOURCES
;
555 if (!(Sha256Update(ctx
, password
, pw_length
))) {
556 console_notify(L
"Unable to generate hash");
557 status
= EFI_OUT_OF_RESOURCES
;
561 if (!(Sha256Final(ctx
, hash
))) {
562 console_notify(L
"Unable to finalise hash");
563 status
= EFI_OUT_OF_RESOURCES
;
567 status
= EFI_SUCCESS
;
572 static void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE
*SavedMode
)
575 Print(L
"Invalid parameter: SavedMode\n");
579 CopyMem(SavedMode
, ST
->ConOut
->Mode
, sizeof(SIMPLE_TEXT_OUTPUT_MODE
));
580 uefi_call_wrapper(ST
->ConOut
->EnableCursor
, 2, ST
->ConOut
, FALSE
);
581 uefi_call_wrapper(ST
->ConOut
->SetAttribute
, 2, ST
->ConOut
,
582 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
585 static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE
*SavedMode
)
587 uefi_call_wrapper(ST
->ConOut
->EnableCursor
, 2, ST
->ConOut
,
588 SavedMode
->CursorVisible
);
589 uefi_call_wrapper(ST
->ConOut
->SetCursorPosition
, 3, ST
->ConOut
,
590 SavedMode
->CursorColumn
, SavedMode
->CursorRow
);
591 uefi_call_wrapper(ST
->ConOut
->SetAttribute
, 2, ST
->ConOut
,
592 SavedMode
->Attribute
);
595 static UINT32
get_password (CHAR16
*prompt
, CHAR16
*password
, UINT32 max
)
597 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
604 prompt
= L
"Password:";
606 console_save_and_set_mode(&SavedMode
);
608 str
= PoolPrint(L
"%s ", prompt
);
610 console_errorbox(L
"Failed to allocate prompt");
616 length
= StrLen(message
[0]);
617 console_print_box_at(message
, -1, -length
-4, -5, length
+4, 3, 0, 1);
618 get_line(&pw_length
, password
, max
, 0);
620 console_restore_mode(&SavedMode
);
627 static EFI_STATUS
match_password (PASSWORD_CRYPT
*pw_crypt
,
628 void *Data
, UINTN DataSize
,
629 UINT8
*auth
, CHAR16
*prompt
)
635 CHAR16 password
[PASSWORD_MAX
];
637 UINT8 fail_count
= 0;
641 auth_hash
= pw_crypt
->hash
;
642 auth_size
= get_hash_size (pw_crypt
->method
);
644 return EFI_INVALID_PARAMETER
;
647 auth_size
= SHA256_DIGEST_SIZE
;
649 return EFI_INVALID_PARAMETER
;
652 while (fail_count
< 3) {
653 pw_length
= get_password(prompt
, password
, PASSWORD_MAX
);
655 if (pw_length
< PASSWORD_MIN
|| pw_length
> PASSWORD_MAX
) {
656 console_errorbox(L
"Invalid password length");
662 * Compute password hash
665 char pw_ascii
[PASSWORD_MAX
+ 1];
666 for (i
= 0; i
< pw_length
; i
++)
667 pw_ascii
[i
] = (char)password
[i
];
668 pw_ascii
[pw_length
] = '\0';
670 status
= password_crypt(pw_ascii
, pw_length
, pw_crypt
, hash
);
673 * For backward compatibility
675 status
= compute_pw_hash(Data
, DataSize
, (UINT8
*)password
,
676 pw_length
* sizeof(CHAR16
), hash
);
678 if (status
!= EFI_SUCCESS
) {
679 console_errorbox(L
"Unable to generate password hash");
684 if (CompareMem(auth_hash
, hash
, auth_size
) != 0) {
685 console_errorbox(L
"Password doesn't match");
694 return EFI_ACCESS_DENIED
;
699 static EFI_STATUS
store_keys (void *MokNew
, UINTN MokNewSize
, int authenticate
)
701 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
702 EFI_STATUS efi_status
;
703 UINT8 auth
[PASSWORD_CRYPT_SIZE
];
704 UINTN auth_size
= PASSWORD_CRYPT_SIZE
;
708 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokAuth",
710 &attributes
, &auth_size
, auth
);
712 if (efi_status
!= EFI_SUCCESS
||
713 (auth_size
!= SHA256_DIGEST_SIZE
&&
714 auth_size
!= PASSWORD_CRYPT_SIZE
)) {
715 console_error(L
"Failed to get MokAuth", efi_status
);
719 if (auth_size
== PASSWORD_CRYPT_SIZE
) {
720 efi_status
= match_password((PASSWORD_CRYPT
*)auth
,
721 NULL
, 0, NULL
, NULL
);
723 efi_status
= match_password(NULL
, MokNew
, MokNewSize
,
726 if (efi_status
!= EFI_SUCCESS
)
727 return EFI_ACCESS_DENIED
;
732 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5, L
"MokList",
734 EFI_VARIABLE_NON_VOLATILE
735 | EFI_VARIABLE_BOOTSERVICE_ACCESS
,
739 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5, L
"MokList",
741 EFI_VARIABLE_NON_VOLATILE
742 | EFI_VARIABLE_BOOTSERVICE_ACCESS
743 | EFI_VARIABLE_APPEND_WRITE
,
747 if (efi_status
!= EFI_SUCCESS
) {
748 console_error(L
"Failed to set variable", efi_status
);
755 static UINTN
mok_enrollment_prompt (void *MokNew
, UINTN MokNewSize
, int auth
) {
756 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
757 EFI_STATUS efi_status
;
759 if (list_keys(MokNew
, MokNewSize
, L
"[Enroll MOK]") != EFI_SUCCESS
)
762 if (console_yes_no((CHAR16
*[]){L
"Enroll the key(s)?", NULL
}) == 0)
765 efi_status
= store_keys(MokNew
, MokNewSize
, auth
);
767 if (efi_status
!= EFI_SUCCESS
) {
768 console_notify(L
"Failed to enroll keys\n");
773 LibDeleteVariable(L
"MokNew", &shim_lock_guid
);
774 LibDeleteVariable(L
"MokAuth", &shim_lock_guid
);
776 console_notify(L
"The system must now be rebooted");
777 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
778 EFI_SUCCESS
, 0, NULL
);
779 console_notify(L
"Failed to reboot");
786 static INTN
mok_reset_prompt ()
788 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
789 EFI_STATUS efi_status
;
791 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
793 if (console_yes_no((CHAR16
*[]){L
"Erase all stored keys?", NULL
}) == 0)
796 efi_status
= store_keys(NULL
, 0, TRUE
);
798 if (efi_status
!= EFI_SUCCESS
) {
799 console_notify(L
"Failed to erase keys\n");
803 LibDeleteVariable(L
"MokNew", &shim_lock_guid
);
804 LibDeleteVariable(L
"MokAuth", &shim_lock_guid
);
806 console_notify(L
"The system must now be rebooted");
807 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
808 EFI_SUCCESS
, 0, NULL
);
809 console_notify(L
"Failed to reboot\n");
813 static EFI_STATUS
write_back_mok_list (MokListNode
*list
, INTN key_num
)
815 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
816 EFI_STATUS efi_status
;
817 EFI_SIGNATURE_LIST
*CertList
;
818 EFI_SIGNATURE_DATA
*CertData
;
819 void *Data
= NULL
, *ptr
;
823 for (i
= 0; i
< key_num
; i
++) {
824 if (list
[i
].Mok
== NULL
)
827 DataSize
+= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_GUID
);
828 DataSize
+= list
[i
].MokSize
;
831 Data
= AllocatePool(DataSize
);
832 if (Data
== NULL
&& DataSize
!= 0)
833 return EFI_OUT_OF_RESOURCES
;
837 for (i
= 0; i
< key_num
; i
++) {
838 if (list
[i
].Mok
== NULL
)
841 CertList
= (EFI_SIGNATURE_LIST
*)ptr
;
842 CertData
= (EFI_SIGNATURE_DATA
*)(((uint8_t *)ptr
) +
843 sizeof(EFI_SIGNATURE_LIST
));
845 CertList
->SignatureType
= list
[i
].Type
;
846 CertList
->SignatureListSize
= list
[i
].MokSize
+
847 sizeof(EFI_SIGNATURE_LIST
) +
848 sizeof(EFI_SIGNATURE_DATA
) - 1;
849 CertList
->SignatureHeaderSize
= 0;
850 CertList
->SignatureSize
= list
[i
].MokSize
+ sizeof(EFI_GUID
);
852 CertData
->SignatureOwner
= shim_lock_guid
;
853 CopyMem(CertData
->SignatureData
, list
[i
].Mok
, list
[i
].MokSize
);
855 ptr
= (uint8_t *)ptr
+ sizeof(EFI_SIGNATURE_LIST
) +
856 sizeof(EFI_GUID
) + list
[i
].MokSize
;
859 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5, L
"MokList",
861 EFI_VARIABLE_NON_VOLATILE
862 | EFI_VARIABLE_BOOTSERVICE_ACCESS
,
867 if (efi_status
!= EFI_SUCCESS
) {
868 console_error(L
"Failed to set variable", efi_status
);
875 static EFI_STATUS
delete_keys (void *MokDel
, UINTN MokDelSize
)
877 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
878 EFI_STATUS efi_status
;
879 UINT8 auth
[PASSWORD_CRYPT_SIZE
];
880 UINTN auth_size
= PASSWORD_CRYPT_SIZE
;
882 UINT8
*MokListData
= NULL
;
883 UINTN MokListDataSize
= 0;
884 MokListNode
*mok
, *del_key
;
885 INTN mok_num
, del_num
;
888 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokDelAuth",
890 &attributes
, &auth_size
, auth
);
892 if (efi_status
!= EFI_SUCCESS
||
893 (auth_size
!= SHA256_DIGEST_SIZE
&& auth_size
!= PASSWORD_CRYPT_SIZE
)) {
894 console_error(L
"Failed to get MokDelAuth", efi_status
);
898 if (auth_size
== PASSWORD_CRYPT_SIZE
) {
899 efi_status
= match_password((PASSWORD_CRYPT
*)auth
, NULL
, 0,
902 efi_status
= match_password(NULL
, MokDel
, MokDelSize
, auth
, NULL
);
904 if (efi_status
!= EFI_SUCCESS
)
905 return EFI_ACCESS_DENIED
;
907 efi_status
= get_variable_attr (L
"MokList", &MokListData
, &MokListDataSize
,
908 shim_lock_guid
, &attributes
);
909 if (attributes
& EFI_VARIABLE_RUNTIME_ACCESS
) {
910 console_alertbox((CHAR16
*[]){L
"MokList is compromised!",
911 L
"Erase all keys in MokList!",
913 if (LibDeleteVariable(L
"MokList", &shim_lock_guid
) != EFI_SUCCESS
) {
914 console_notify(L
"Failed to erase MokList");
916 return EFI_ACCESS_DENIED
;
920 if (!MokListData
|| MokListDataSize
== 0)
923 /* Construct lists */
924 mok_num
= count_keys(MokListData
, MokListDataSize
);
925 mok
= build_mok_list(mok_num
, MokListData
, MokListDataSize
);
926 del_num
= count_keys(MokDel
, MokDelSize
);
927 del_key
= build_mok_list(del_num
, MokDel
, MokDelSize
);
929 /* Search and destroy */
930 for (i
= 0; i
< del_num
; i
++) {
931 UINT32 key_size
= del_key
[i
].MokSize
;
932 void *key
= del_key
[i
].Mok
;
933 for (j
= 0; j
< mok_num
; j
++) {
934 if (mok
[j
].MokSize
== key_size
&&
935 CompareMem(key
, mok
[j
].Mok
, key_size
) == 0) {
943 efi_status
= write_back_mok_list(mok
, mok_num
);
946 FreePool(MokListData
);
955 static INTN
mok_deletion_prompt (void *MokDel
, UINTN MokDelSize
)
957 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
958 EFI_STATUS efi_status
;
960 if (list_keys(MokDel
, MokDelSize
, L
"[Delete MOK]") != EFI_SUCCESS
) {
964 if (console_yes_no((CHAR16
*[]){L
"Delete the key(s)?", NULL
}) == 0)
967 efi_status
= delete_keys(MokDel
, MokDelSize
);
969 if (efi_status
!= EFI_SUCCESS
) {
970 console_notify(L
"Failed to delete keys");
974 LibDeleteVariable(L
"MokDel", &shim_lock_guid
);
975 LibDeleteVariable(L
"MokDelAuth", &shim_lock_guid
);
977 console_notify(L
"The system must now be rebooted");
978 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
979 EFI_SUCCESS
, 0, NULL
);
980 console_notify(L
"Failed to reboot");
984 static CHAR16
get_password_charater (CHAR16
*prompt
)
986 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
993 prompt
= L
"Password charater: ";
995 console_save_and_set_mode(&SavedMode
);
999 length
= StrLen(message
[0]);
1000 console_print_box_at(message
, -1, -length
-4, -5, length
+4, 3, 0, 1);
1001 get_line(&pw_length
, &character
, 1, 0);
1003 console_restore_mode(&SavedMode
);
1008 static INTN
mok_sb_prompt (void *MokSB
, UINTN MokSBSize
) {
1009 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1010 EFI_STATUS efi_status
;
1011 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
1012 MokSBvar
*var
= MokSB
;
1014 CHAR16 pass1
, pass2
, pass3
;
1016 UINT8 fail_count
= 0;
1018 UINT8 pos1
, pos2
, pos3
;
1021 if (MokSBSize
!= sizeof(MokSBvar
)) {
1022 console_notify(L
"Invalid MokSB variable contents");
1026 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
1028 message
[0] = L
"Change Secure Boot state";
1031 console_save_and_set_mode(&SavedMode
);
1032 console_print_box_at(message
, -1, 0, 0, -1, -1, 1, 1);
1033 console_restore_mode(&SavedMode
);
1035 while (fail_count
< 3) {
1036 RandomBytes (&pos1
, sizeof(pos1
));
1037 pos1
= (pos1
% var
->PWLen
);
1040 RandomBytes (&pos2
, sizeof(pos2
));
1041 pos2
= (pos2
% var
->PWLen
);
1042 } while (pos2
== pos1
);
1045 RandomBytes (&pos3
, sizeof(pos3
));
1046 pos3
= (pos3
% var
->PWLen
) ;
1047 } while (pos3
== pos2
|| pos3
== pos1
);
1049 str
= PoolPrint(L
"Enter password character %d: ", pos1
+ 1);
1051 console_errorbox(L
"Failed to allocate buffer");
1054 pass1
= get_password_charater(str
);
1057 str
= PoolPrint(L
"Enter password character %d: ", pos2
+ 1);
1059 console_errorbox(L
"Failed to allocate buffer");
1062 pass2
= get_password_charater(str
);
1065 str
= PoolPrint(L
"Enter password character %d: ", pos3
+ 1);
1067 console_errorbox(L
"Failed to allocate buffer");
1070 pass3
= get_password_charater(str
);
1073 if (pass1
!= var
->Password
[pos1
] ||
1074 pass2
!= var
->Password
[pos2
] ||
1075 pass3
!= var
->Password
[pos3
]) {
1076 Print(L
"Invalid character\n");
1083 if (fail_count
>= 3) {
1084 console_notify(L
"Password limit reached");
1088 if (var
->MokSBState
== 0)
1089 ret
= console_yes_no((CHAR16
*[]){L
"Disable Secure Boot", NULL
});
1091 ret
= console_yes_no((CHAR16
*[]){L
"Enable Secure Boot", NULL
});
1094 LibDeleteVariable(L
"MokSB", &shim_lock_guid
);
1098 if (var
->MokSBState
== 0) {
1099 efi_status
= uefi_call_wrapper(RT
->SetVariable
,
1102 EFI_VARIABLE_NON_VOLATILE
|
1103 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1105 if (efi_status
!= EFI_SUCCESS
) {
1106 console_notify(L
"Failed to set Secure Boot state");
1110 LibDeleteVariable(L
"MokSBState", &shim_lock_guid
);
1113 console_notify(L
"The system must now be rebooted");
1114 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
1115 EFI_SUCCESS
, 0, NULL
);
1116 console_notify(L
"Failed to reboot");
1120 static INTN
mok_pw_prompt (void *MokPW
, UINTN MokPWSize
) {
1121 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1122 EFI_STATUS efi_status
;
1123 UINT8 hash
[PASSWORD_CRYPT_SIZE
];
1126 if (MokPWSize
!= SHA256_DIGEST_SIZE
&& MokPWSize
!= PASSWORD_CRYPT_SIZE
) {
1127 console_notify(L
"Invalid MokPW variable contents");
1131 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
1133 SetMem(hash
, PASSWORD_CRYPT_SIZE
, 0);
1135 if (MokPWSize
== PASSWORD_CRYPT_SIZE
) {
1136 if (CompareMem(MokPW
, hash
, PASSWORD_CRYPT_SIZE
) == 0)
1139 if (CompareMem(MokPW
, hash
, SHA256_DIGEST_SIZE
) == 0)
1144 if (console_yes_no((CHAR16
*[]){L
"Clear MOK password?", NULL
}) == 0)
1147 LibDeleteVariable(L
"MokPWStore", &shim_lock_guid
);
1148 LibDeleteVariable(L
"MokPW", &shim_lock_guid
);
1149 console_notify(L
"The system must now be rebooted");
1150 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
, EFI_SUCCESS
, 0,
1152 console_notify(L
"Failed to reboot");
1156 if (MokPWSize
== PASSWORD_CRYPT_SIZE
) {
1157 efi_status
= match_password((PASSWORD_CRYPT
*)MokPW
, NULL
, 0,
1158 NULL
, L
"Confirm MOK passphrase: ");
1160 efi_status
= match_password(NULL
, NULL
, 0, MokPW
,
1161 L
"Confirm MOK passphrase: ");
1164 if (efi_status
!= EFI_SUCCESS
) {
1165 console_notify(L
"Password limit reached");
1169 if (console_yes_no((CHAR16
*[]){L
"Set MOK password?", NULL
}) == 0)
1172 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5,
1175 EFI_VARIABLE_NON_VOLATILE
|
1176 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1178 if (efi_status
!= EFI_SUCCESS
) {
1179 console_notify(L
"Failed to set MOK password");
1183 LibDeleteVariable(L
"MokPW", &shim_lock_guid
);
1185 console_notify(L
"The system must now be rebooted");
1186 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
, EFI_SUCCESS
, 0,
1188 console_notify(L
"Failed to reboot");
1192 static BOOLEAN
verify_certificate(void *cert
, UINTN size
)
1195 if (!cert
|| size
== 0)
1198 if (!(X509ConstructCertificate(cert
, size
, (UINT8
**) &X509Cert
)) ||
1200 console_notify(L
"Invalid X509 certificate");
1204 X509_free(X509Cert
);
1208 static EFI_STATUS
enroll_file (void *data
, UINTN datasize
, BOOLEAN hash
)
1210 EFI_STATUS status
= EFI_SUCCESS
;
1211 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1212 EFI_SIGNATURE_LIST
*CertList
;
1213 EFI_SIGNATURE_DATA
*CertData
;
1214 UINTN mokbuffersize
;
1215 void *mokbuffer
= NULL
;
1218 UINT8 sha256
[SHA256_DIGEST_SIZE
];
1219 UINT8 sha1
[SHA1_DIGEST_SIZE
];
1220 SHIM_LOCK
*shim_lock
;
1221 EFI_GUID shim_guid
= SHIM_LOCK_GUID
;
1222 PE_COFF_LOADER_IMAGE_CONTEXT context
;
1224 status
= LibLocateProtocol(&shim_guid
, (VOID
**)&shim_lock
);
1226 if (status
!= EFI_SUCCESS
)
1229 mokbuffersize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_GUID
) +
1232 mokbuffer
= AllocatePool(mokbuffersize
);
1237 status
= shim_lock
->Context(data
, datasize
, &context
);
1239 if (status
!= EFI_SUCCESS
)
1242 status
= shim_lock
->Hash(data
, datasize
, &context
, sha256
,
1245 if (status
!= EFI_SUCCESS
)
1248 CertList
= mokbuffer
;
1249 CertList
->SignatureType
= EFI_CERT_SHA256_GUID
;
1250 CertList
->SignatureSize
= 16 + SHA256_DIGEST_SIZE
;
1251 CertData
= (EFI_SIGNATURE_DATA
*)(((UINT8
*)mokbuffer
) +
1252 sizeof(EFI_SIGNATURE_LIST
));
1253 CopyMem(CertData
->SignatureData
, sha256
, SHA256_DIGEST_SIZE
);
1255 mokbuffersize
= datasize
+ sizeof(EFI_SIGNATURE_LIST
) +
1257 mokbuffer
= AllocatePool(mokbuffersize
);
1262 CertList
= mokbuffer
;
1263 CertList
->SignatureType
= X509_GUID
;
1264 CertList
->SignatureSize
= 16 + datasize
;
1266 memcpy(mokbuffer
+ sizeof(EFI_SIGNATURE_LIST
) + 16, data
,
1269 CertData
= (EFI_SIGNATURE_DATA
*)(((UINT8
*)mokbuffer
) +
1270 sizeof(EFI_SIGNATURE_LIST
));
1273 CertList
->SignatureListSize
= mokbuffersize
;
1274 CertList
->SignatureHeaderSize
= 0;
1275 CertData
->SignatureOwner
= shim_lock_guid
;
1278 if (!verify_certificate(CertData
->SignatureData
, datasize
))
1282 mok_enrollment_prompt(mokbuffer
, mokbuffersize
, FALSE
);
1285 FreePool(mokbuffer
);
1290 static void mok_hash_enroll(void)
1292 EFI_STATUS efi_status
;
1293 CHAR16
*file_name
= NULL
;
1294 EFI_HANDLE im
= NULL
;
1295 EFI_FILE
*file
= NULL
;
1299 simple_file_selector(&im
, (CHAR16
*[]){
1302 L
"The Selected Binary will have its hash Enrolled",
1303 L
"This means it will Subsequently Boot with no prompting",
1304 L
"Remember to make sure it is a genuine binary before Enroling its hash",
1306 }, L
"\\", L
"", &file_name
);
1311 efi_status
= simple_file_open(im
, file_name
, &file
, EFI_FILE_MODE_READ
);
1313 if (efi_status
!= EFI_SUCCESS
) {
1314 console_error(L
"Unable to open file", efi_status
);
1318 simple_file_read_all(file
, &filesize
, &data
);
1319 simple_file_close(file
);
1322 console_error(L
"Unable to read file", efi_status
);
1326 efi_status
= enroll_file(data
, filesize
, TRUE
);
1328 if (efi_status
!= EFI_SUCCESS
)
1329 console_error(L
"Hash failed (did you select a valid EFI binary?)", efi_status
);
1334 static CHAR16
*der_suffix
[] = {
1341 static BOOLEAN
check_der_suffix (CHAR16
*file_name
)
1346 if (!file_name
|| StrLen(file_name
) <= 4)
1350 StrCat(suffix
, file_name
+ StrLen(file_name
) - 4);
1353 for (i
= 0; der_suffix
[i
] != NULL
; i
++) {
1354 if (StrCmp(suffix
, der_suffix
[i
]) == 0) {
1362 static void mok_key_enroll(void)
1364 EFI_STATUS efi_status
;
1365 CHAR16
*file_name
= NULL
;
1366 EFI_HANDLE im
= NULL
;
1367 EFI_FILE
*file
= NULL
;
1371 simple_file_selector(&im
, (CHAR16
*[]){
1374 L
"The selected key will be enrolled into the MOK database",
1375 L
"This means any binaries signed with it will be run without prompting",
1376 L
"Remember to make sure it is a genuine key before Enroling it",
1378 }, L
"\\", L
"", &file_name
);
1383 if (!check_der_suffix(file_name
)) {
1384 console_alertbox((CHAR16
*[]){
1385 L
"Unsupported Format",
1387 L
"Only DER encoded certificate (*.cer/der/crt) is supported",
1392 efi_status
= simple_file_open(im
, file_name
, &file
, EFI_FILE_MODE_READ
);
1394 if (efi_status
!= EFI_SUCCESS
) {
1395 console_error(L
"Unable to open file", efi_status
);
1399 simple_file_read_all(file
, &filesize
, &data
);
1400 simple_file_close(file
);
1403 console_error(L
"Unable to read file", efi_status
);
1407 enroll_file(data
, filesize
, FALSE
);
1411 static BOOLEAN
verify_pw(BOOLEAN
*protected)
1413 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1414 EFI_STATUS efi_status
;
1415 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
1416 UINT8 pwhash
[PASSWORD_CRYPT_SIZE
];
1417 UINTN size
= PASSWORD_CRYPT_SIZE
;
1423 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokPWStore",
1424 &shim_lock_guid
, &attributes
, &size
,
1428 * If anything can attack the password it could just set it to a
1429 * known value, so there's no safety advantage in failing to validate
1430 * purely because of a failure to read the variable
1432 if (efi_status
!= EFI_SUCCESS
||
1433 (size
!= SHA256_DIGEST_SIZE
&& size
!= PASSWORD_CRYPT_SIZE
))
1436 if (attributes
& EFI_VARIABLE_RUNTIME_ACCESS
)
1439 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
1441 /* Draw the background */
1442 console_save_and_set_mode(&SavedMode
);
1443 message
[0] = PoolPrint (L
"%s UEFI key management", SHIM_VENDOR
);
1445 console_print_box_at(message
, -1, 0, 0, -1, -1, 1, 1);
1446 FreePool(message
[0]);
1447 console_restore_mode(&SavedMode
);
1449 if (size
== PASSWORD_CRYPT_SIZE
) {
1450 efi_status
= match_password((PASSWORD_CRYPT
*)pwhash
, NULL
, 0,
1451 NULL
, L
"Enter MOK password:");
1453 efi_status
= match_password(NULL
, NULL
, 0, pwhash
,
1454 L
"Enter MOK password:");
1456 if (efi_status
!= EFI_SUCCESS
) {
1457 console_notify(L
"Password limit reached");
1466 static int draw_countdown()
1468 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
1473 CHAR16
*message
= L
"Press any key to perform MOK management";
1474 int timeout
= 10, wait
= 10000000;
1476 console_save_and_set_mode (&SavedMode
);
1478 title
[0] = PoolPrint (L
"%s UEFI key management", SHIM_VENDOR
);
1481 console_print_box_at(title
, -1, 0, 0, -1, -1, 1, 1);
1483 uefi_call_wrapper(ST
->ConOut
->QueryMode
, 4, ST
->ConOut
,
1484 ST
->ConOut
->Mode
->Mode
, &cols
, &rows
);
1486 PrintAt((cols
- StrLen(message
))/2, rows
/2, message
);
1489 PrintAt(2, rows
- 3, L
"Booting in %d seconds ", timeout
);
1491 PrintAt(2, rows
- 3, L
"Booting in %d second ", timeout
);
1493 status
= WaitForSingleEvent(ST
->ConIn
->WaitForKey
, wait
);
1495 if (status
!= EFI_TIMEOUT
) {
1496 /* Clear the key in the queue */
1497 uefi_call_wrapper(ST
->ConIn
->ReadKeyStroke
, 2,
1509 console_restore_mode(&SavedMode
);
1525 static EFI_STATUS
enter_mok_menu(EFI_HANDLE image_handle
,
1526 void *MokNew
, UINTN MokNewSize
,
1527 void *MokDel
, UINTN MokDelSize
,
1528 void *MokSB
, UINTN MokSBSize
,
1529 void *MokPW
, UINTN MokPWSize
)
1531 CHAR16
**menu_strings
;
1532 mok_menu_item
*menu_item
;
1535 UINT32 MokDelAuth
= 0;
1536 UINTN menucount
= 3, i
= 0;
1537 EFI_STATUS efi_status
;
1538 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1539 UINT8 auth
[PASSWORD_CRYPT_SIZE
];
1540 UINTN auth_size
= PASSWORD_CRYPT_SIZE
;
1543 EFI_STATUS ret
= EFI_SUCCESS
;
1545 if (verify_pw(&protected) == FALSE
)
1546 return EFI_ACCESS_DENIED
;
1548 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokAuth",
1550 &attributes
, &auth_size
, auth
);
1552 if ((efi_status
== EFI_SUCCESS
) &&
1553 (auth_size
== SHA256_DIGEST_SIZE
|| auth_size
== PASSWORD_CRYPT_SIZE
))
1556 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokDelAuth",
1558 &attributes
, &auth_size
, auth
);
1560 if ((efi_status
== EFI_SUCCESS
) &&
1561 (auth_size
== SHA256_DIGEST_SIZE
|| auth_size
== PASSWORD_CRYPT_SIZE
))
1564 if (MokNew
|| MokAuth
)
1567 if (MokDel
|| MokDelAuth
)
1576 menu_strings
= AllocateZeroPool(sizeof(CHAR16
*) * (menucount
+ 1));
1579 return EFI_OUT_OF_RESOURCES
;
1581 menu_item
= AllocateZeroPool(sizeof(mok_menu_item
) * menucount
);
1584 FreePool(menu_strings
);
1585 return EFI_OUT_OF_RESOURCES
;
1588 menu_strings
[i
] = L
"Continue boot";
1589 menu_item
[i
] = MOK_CONTINUE_BOOT
;
1593 if (MokNew
|| MokAuth
) {
1595 menu_strings
[i
] = L
"Reset MOK";
1596 menu_item
[i
] = MOK_RESET_MOK
;
1598 menu_strings
[i
] = L
"Enroll MOK";
1599 menu_item
[i
] = MOK_ENROLL_MOK
;
1604 if (MokDel
|| MokDelAuth
) {
1605 menu_strings
[i
] = L
"Delete MOK";
1606 menu_item
[i
] = MOK_DELETE_MOK
;
1611 menu_strings
[i
] = L
"Change Secure Boot state";
1612 menu_item
[i
] = MOK_CHANGE_SB
;
1617 menu_strings
[i
] = L
"Set MOK password";
1618 menu_item
[i
] = MOK_SET_PW
;
1622 menu_strings
[i
] = L
"Enroll key from disk";
1623 menu_item
[i
] = MOK_KEY_ENROLL
;
1626 menu_strings
[i
] = L
"Enroll hash from disk";
1627 menu_item
[i
] = MOK_HASH_ENROLL
;
1630 menu_strings
[i
] = NULL
;
1632 if (protected == FALSE
&& draw_countdown() == 0)
1635 while (choice
>= 0) {
1636 choice
= console_select((CHAR16
*[]){ L
"Perform MOK management", NULL
},
1642 switch (menu_item
[choice
]) {
1643 case MOK_CONTINUE_BOOT
:
1648 case MOK_ENROLL_MOK
:
1649 mok_enrollment_prompt(MokNew
, MokNewSize
, TRUE
);
1651 case MOK_DELETE_MOK
:
1652 mok_deletion_prompt(MokDel
, MokDelSize
);
1655 mok_sb_prompt(MokSB
, MokSBSize
);
1658 mok_pw_prompt(MokPW
, MokPWSize
);
1660 case MOK_KEY_ENROLL
:
1663 case MOK_HASH_ENROLL
:
1672 FreePool(menu_strings
);
1675 FreePool(menu_item
);
1680 static EFI_STATUS
check_mok_request(EFI_HANDLE image_handle
)
1682 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1683 UINTN MokNewSize
= 0, MokDelSize
= 0, MokSBSize
= 0, MokPWSize
= 0;
1684 void *MokNew
= NULL
;
1685 void *MokDel
= NULL
;
1690 status
= get_variable(L
"MokNew", (UINT8
**)&MokNew
, &MokNewSize
,
1692 if (status
== EFI_SUCCESS
) {
1693 if (LibDeleteVariable(L
"MokNew", &shim_lock_guid
) != EFI_SUCCESS
) {
1694 console_notify(L
"Failed to delete MokNew");
1696 } else if (EFI_ERROR(status
) && status
!= EFI_NOT_FOUND
) {
1697 console_error(L
"Could not retrieve MokNew", status
);
1700 status
= get_variable(L
"MokDel", (UINT8
**)&MokDel
, &MokDelSize
,
1702 if (status
== EFI_SUCCESS
) {
1703 if (LibDeleteVariable(L
"MokDel", &shim_lock_guid
) != EFI_SUCCESS
) {
1704 console_notify(L
"Failed to delete MokDel");
1706 } else if (EFI_ERROR(status
) && status
!= EFI_NOT_FOUND
) {
1707 console_error(L
"Could not retrieve MokDel", status
);
1710 status
= get_variable(L
"MokSB", (UINT8
**)&MokSB
, &MokSBSize
,
1712 if (status
== EFI_SUCCESS
) {
1713 if (LibDeleteVariable(L
"MokSB", &shim_lock_guid
) != EFI_SUCCESS
) {
1714 console_notify(L
"Failed to delete MokSB");
1716 } else if (EFI_ERROR(status
) && status
!= EFI_NOT_FOUND
) {
1717 console_error(L
"Could not retrieve MokSB", status
);
1720 status
= get_variable(L
"MokPW", (UINT8
**)&MokPW
, &MokPWSize
,
1722 if (status
== EFI_SUCCESS
) {
1723 if (LibDeleteVariable(L
"MokPW", &shim_lock_guid
) != EFI_SUCCESS
) {
1724 console_notify(L
"Failed to delete MokPW");
1726 } else if (EFI_ERROR(status
) && status
!= EFI_NOT_FOUND
) {
1727 console_error(L
"Could not retrieve MokPW", status
);
1730 enter_mok_menu(image_handle
, MokNew
, MokNewSize
, MokDel
, MokDelSize
,
1731 MokSB
, MokSBSize
, MokPW
, MokPWSize
);
1745 LibDeleteVariable(L
"MokAuth", &shim_lock_guid
);
1746 LibDeleteVariable(L
"MokDelAuth", &shim_lock_guid
);
1751 static EFI_STATUS
setup_rand (void)
1754 EFI_STATUS efi_status
;
1758 efi_status
= uefi_call_wrapper(RT
->GetTime
, 2, &time
, NULL
);
1760 if (efi_status
!= EFI_SUCCESS
)
1763 seed
= ((UINT64
)time
.Year
<< 48) | ((UINT64
)time
.Month
<< 40) |
1764 ((UINT64
)time
.Day
<< 32) | ((UINT64
)time
.Hour
<< 24) |
1765 ((UINT64
)time
.Minute
<< 16) | ((UINT64
)time
.Second
<< 8) |
1766 ((UINT64
)time
.Daylight
);
1768 status
= RandomSeed((UINT8
*)&seed
, sizeof(seed
));
1776 EFI_STATUS
efi_main (EFI_HANDLE image_handle
, EFI_SYSTEM_TABLE
*systab
)
1778 EFI_STATUS efi_status
;
1780 InitializeLib(image_handle
, systab
);
1786 efi_status
= check_mok_request(image_handle
);