3 #include <Library/BaseCryptLib.h>
4 #include <openssl/x509.h>
5 #include "console_control.h"
9 #include "PasswordCrypt.h"
11 #include "include/console.h"
12 #include "include/simple_file.h"
14 #define PASSWORD_MAX 256
15 #define PASSWORD_MIN 1
16 #define SB_PASSWORD_LEN 16
19 #define SHIM_VENDOR L"Shim"
22 #define EFI_VARIABLE_APPEND_WRITE 0x00000040
24 EFI_GUID SHIM_LOCK_GUID
= { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
26 #define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
27 #define HASH_STRING L"Select a file to trust:\n\n"
31 INTN (* callback
)(void *data
, void *data2
, void *data3
);
42 } __attribute__ ((packed
)) MokListNode
;
47 CHAR16 Password
[SB_PASSWORD_LEN
];
48 } __attribute__ ((packed
)) MokSBvar
;
50 static EFI_STATUS
get_variable (CHAR16
*name
, EFI_GUID guid
, UINT32
*attributes
,
51 UINTN
*size
, void **buffer
)
53 EFI_STATUS efi_status
;
54 char allocate
= !(*size
);
56 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, name
, &guid
,
57 attributes
, size
, buffer
);
59 if (efi_status
!= EFI_BUFFER_TOO_SMALL
|| !allocate
) {
63 *buffer
= AllocatePool(*size
);
66 console_notify(L
"Unable to allocate variable buffer");
67 return EFI_OUT_OF_RESOURCES
;
70 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, name
, &guid
,
71 attributes
, size
, *buffer
);
76 static EFI_STATUS
get_sha1sum (void *Data
, int DataSize
, UINT8
*hash
)
82 ctxsize
= Sha1GetContextSize();
83 ctx
= AllocatePool(ctxsize
);
86 console_notify(L
"Unable to allocate memory for hash context");
87 return EFI_OUT_OF_RESOURCES
;
91 console_notify(L
"Unable to initialise hash");
92 status
= EFI_OUT_OF_RESOURCES
;
96 if (!(Sha1Update(ctx
, Data
, DataSize
))) {
97 console_notify(L
"Unable to generate hash");
98 status
= EFI_OUT_OF_RESOURCES
;
102 if (!(Sha1Final(ctx
, hash
))) {
103 console_notify(L
"Unable to finalise hash");
104 status
= EFI_OUT_OF_RESOURCES
;
108 status
= EFI_SUCCESS
;
113 static UINT32
count_keys(void *Data
, UINTN DataSize
)
115 EFI_SIGNATURE_LIST
*CertList
= Data
;
116 EFI_GUID CertType
= EfiCertX509Guid
;
117 EFI_GUID HashType
= EfiHashSha256Guid
;
118 UINTN dbsize
= DataSize
;
121 while ((dbsize
> 0) && (dbsize
>= CertList
->SignatureListSize
)) {
122 if ((CompareGuid (&CertList
->SignatureType
, &CertType
) != 0) &&
123 (CompareGuid (&CertList
->SignatureType
, &HashType
) != 0)) {
124 console_notify(L
"Doesn't look like a key or hash");
125 dbsize
-= CertList
->SignatureListSize
;
126 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
127 CertList
->SignatureListSize
);
131 if ((CompareGuid (&CertList
->SignatureType
, &CertType
) != 0) &&
132 (CertList
->SignatureSize
!= 48)) {
133 console_notify(L
"Doesn't look like a valid hash");
134 dbsize
-= CertList
->SignatureListSize
;
135 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
136 CertList
->SignatureListSize
);
141 dbsize
-= CertList
->SignatureListSize
;
142 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
143 CertList
->SignatureListSize
);
149 static MokListNode
*build_mok_list(UINT32 num
, void *Data
, UINTN DataSize
) {
151 EFI_SIGNATURE_LIST
*CertList
= Data
;
152 EFI_SIGNATURE_DATA
*Cert
;
153 EFI_GUID CertType
= EfiCertX509Guid
;
154 EFI_GUID HashType
= EfiHashSha256Guid
;
155 UINTN dbsize
= DataSize
;
158 list
= AllocatePool(sizeof(MokListNode
) * num
);
161 console_notify(L
"Unable to allocate MOK list");
165 while ((dbsize
> 0) && (dbsize
>= CertList
->SignatureListSize
)) {
166 if ((CompareGuid (&CertList
->SignatureType
, &CertType
) != 0) &&
167 (CompareGuid (&CertList
->SignatureType
, &HashType
) != 0)) {
168 dbsize
-= CertList
->SignatureListSize
;
169 CertList
= (EFI_SIGNATURE_LIST
*)((UINT8
*) CertList
+
170 CertList
->SignatureListSize
);
174 if ((CompareGuid (&CertList
->SignatureType
, &HashType
) == 0) &&
175 (CertList
->SignatureSize
!= 48)) {
176 dbsize
-= CertList
->SignatureListSize
;
177 CertList
= (EFI_SIGNATURE_LIST
*)((UINT8
*) CertList
+
178 CertList
->SignatureListSize
);
182 Cert
= (EFI_SIGNATURE_DATA
*) (((UINT8
*) CertList
) +
183 sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
185 list
[count
].MokSize
= CertList
->SignatureSize
- sizeof(EFI_GUID
);
186 list
[count
].Mok
= (void *)Cert
->SignatureData
;
187 list
[count
].Type
= CertList
->SignatureType
;
190 dbsize
-= CertList
->SignatureListSize
;
191 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+
192 CertList
->SignatureListSize
);
198 static CHAR16
* get_x509_name (X509_NAME
*X509Name
, CHAR16
*name
)
203 str
= X509_NAME_oneline(X509Name
, NULL
, 0);
205 ret
= PoolPrint(L
"%s: %a", name
, str
);
211 static const char *mon
[12]= {
212 "Jan","Feb","Mar","Apr","May","Jun",
213 "Jul","Aug","Sep","Oct","Nov","Dec"
216 static void print_x509_GENERALIZEDTIME_time (ASN1_TIME
*time
, CHAR16
*time_string
)
221 int y
= 0,M
= 0,d
= 0,h
= 0,m
= 0,s
= 0;
226 v
=(char *)time
->data
;
234 for (i
=0; i
<12; i
++) {
235 if ((v
[i
] > '9') || (v
[i
] < '0'))
239 y
= (v
[0]-'0')*1000+(v
[1]-'0')*100 + (v
[2]-'0')*10+(v
[3]-'0');
240 M
= (v
[4]-'0')*10+(v
[5]-'0');
242 if ((M
> 12) || (M
< 1))
245 d
= (v
[6]-'0')*10+(v
[7]-'0');
246 h
= (v
[8]-'0')*10+(v
[9]-'0');
247 m
= (v
[10]-'0')*10+(v
[11]-'0');
249 if (time
->length
>= 14 &&
250 (v
[12] >= '0') && (v
[12] <= '9') &&
251 (v
[13] >= '0') && (v
[13] <= '9')) {
252 s
= (v
[12]-'0')*10+(v
[13]-'0');
253 /* Check for fractions of seconds. */
254 if (time
->length
>= 15 && v
[14] == '.') {
255 int l
= time
->length
;
256 f
= &v
[14]; /* The decimal point. */
258 while (14 + f_len
< l
&& f
[f_len
] >= '0' &&
264 SPrint(time_string
, 0, L
"%a %2d %02d:%02d:%02d%.*a %d%a",
265 mon
[M
-1], d
, h
, m
, s
, f_len
, f
, y
, (gmt
)?" GMT":"");
270 static void print_x509_UTCTIME_time (ASN1_TIME
*time
, CHAR16
*time_string
)
275 int y
= 0,M
= 0,d
= 0,h
= 0,m
= 0,s
= 0;
278 v
=(char *)time
->data
;
287 if ((v
[i
] > '9') || (v
[i
] < '0'))
290 y
= (v
[0]-'0')*10+(v
[1]-'0');
295 M
= (v
[2]-'0')*10+(v
[3]-'0');
297 if ((M
> 12) || (M
< 1))
300 d
= (v
[4]-'0')*10+(v
[5]-'0');
301 h
= (v
[6]-'0')*10+(v
[7]-'0');
302 m
= (v
[8]-'0')*10+(v
[9]-'0');
304 if (time
->length
>=12 &&
305 (v
[10] >= '0') && (v
[10] <= '9') &&
306 (v
[11] >= '0') && (v
[11] <= '9'))
307 s
= (v
[10]-'0')*10+(v
[11]-'0');
309 SPrint(time_string
, 0, L
"%a %2d %02d:%02d:%02d %d%a",
310 mon
[M
-1], d
, h
, m
, s
, y
+1900, (gmt
)?" GMT":"");
315 static CHAR16
* get_x509_time (ASN1_TIME
*time
, CHAR16
*name
)
317 CHAR16 time_string
[30];
319 if (time
->type
== V_ASN1_UTCTIME
) {
320 print_x509_UTCTIME_time(time
, time_string
);
321 } else if (time
->type
== V_ASN1_GENERALIZEDTIME
) {
322 print_x509_GENERALIZEDTIME_time(time
, time_string
);
324 time_string
[0] = '\0';
327 return PoolPrint(L
"%s: %s", name
, time_string
);
330 static void show_x509_info (X509
*X509Cert
, UINT8
*hash
)
332 ASN1_INTEGER
*serial
;
334 unsigned char hexbuf
[30];
337 CHAR16
*issuer
= NULL
;
338 CHAR16
*subject
= NULL
;
340 CHAR16
*until
= NULL
;
341 POOL_PRINT hash_string1
;
342 POOL_PRINT hash_string2
;
343 POOL_PRINT serial_string
;
348 ZeroMem(&hash_string1
, sizeof(hash_string1
));
349 ZeroMem(&hash_string2
, sizeof(hash_string2
));
350 ZeroMem(&serial_string
, sizeof(serial_string
));
352 serial
= X509_get_serialNumber(X509Cert
);
355 bnser
= ASN1_INTEGER_to_BN(serial
, NULL
);
356 n
= BN_bn2bin(bnser
, hexbuf
);
357 CatPrint(&serial_string
, L
"Serial Number:");
358 for (i
= 0; i
< n
; i
++) {
359 CatPrint(&serial_string
, L
"%02x:", hexbuf
[i
]);
363 if (serial_string
.str
)
366 X509Name
= X509_get_issuer_name(X509Cert
);
368 issuer
= get_x509_name(X509Name
, L
"Issuer");
373 X509Name
= X509_get_subject_name(X509Cert
);
375 subject
= get_x509_name(X509Name
, L
"Subject");
380 time
= X509_get_notBefore(X509Cert
);
382 from
= get_x509_time(time
, L
"Validity from");
387 time
= X509_get_notAfter(X509Cert
);
389 until
= get_x509_time(time
, L
"Validity till");
395 CatPrint(&hash_string1
, L
"SHA1 Fingerprint: ");
397 CatPrint(&hash_string1
, L
"%02x ", hash
[i
]);
398 for (i
=10; i
<20; i
++)
399 CatPrint(&hash_string2
, L
"%02x ", hash
[i
]);
401 if (hash_string1
.str
)
404 if (hash_string2
.str
)
410 text
= AllocateZeroPool(sizeof(CHAR16
*) * (fields
+ 1));
411 if (serial_string
.str
) {
412 text
[i
] = serial_string
.str
;
431 if (hash_string1
.str
) {
432 text
[i
] = hash_string1
.str
;
435 if (hash_string2
.str
) {
436 text
[i
] = hash_string2
.str
;
441 console_alertbox(text
);
443 for (i
=0; text
[i
] != NULL
; i
++)
449 static void show_mok_info (void *Mok
, UINTN MokSize
)
451 EFI_STATUS efi_status
;
452 UINT8 hash
[SHA1_DIGEST_SIZE
];
456 if (!Mok
|| MokSize
== 0)
459 if (MokSize
!= SHA256_DIGEST_SIZE
) {
460 efi_status
= get_sha1sum(Mok
, MokSize
, hash
);
462 if (efi_status
!= EFI_SUCCESS
) {
463 console_notify(L
"Failed to compute MOK fingerprint");
467 if (X509ConstructCertificate(Mok
, MokSize
,
468 (UINT8
**) &X509Cert
) && X509Cert
!= NULL
) {
469 show_x509_info(X509Cert
, hash
);
472 console_notify(L
"Not a valid X509 certificate");
476 Print(L
"SHA256 hash:\n ");
477 for (i
= 0; i
< SHA256_DIGEST_SIZE
; i
++) {
478 Print(L
" %02x", ((UINT8
*)Mok
)[i
]);
486 static EFI_STATUS
list_keys (void *KeyList
, UINTN KeyListSize
, CHAR16
*title
)
489 MokListNode
*keys
= NULL
;
491 CHAR16
**menu_strings
;
494 if (KeyListSize
< (sizeof(EFI_SIGNATURE_LIST
) +
495 sizeof(EFI_SIGNATURE_DATA
))) {
496 console_notify(L
"No MOK keys found");
500 MokNum
= count_keys(KeyList
, KeyListSize
);
501 keys
= build_mok_list(MokNum
, KeyList
, KeyListSize
);
504 console_notify(L
"Failed to construct key list");
508 menu_strings
= AllocateZeroPool(sizeof(CHAR16
*) * (MokNum
+ 2));
511 return EFI_OUT_OF_RESOURCES
;
513 for (i
=0; i
<MokNum
; i
++) {
514 menu_strings
[i
] = PoolPrint(L
"View key %d", i
);
516 menu_strings
[i
] = StrDuplicate(L
"Continue");
518 menu_strings
[i
+1] = NULL
;
520 while (key_num
< MokNum
) {
521 key_num
= console_select((CHAR16
*[]){ title
, NULL
},
524 if (key_num
< MokNum
)
525 show_mok_info(keys
[key_num
].Mok
, keys
[key_num
].MokSize
);
528 for (i
=0; menu_strings
[i
] != NULL
; i
++)
529 FreePool(menu_strings
[i
]);
531 FreePool(menu_strings
);
538 static UINT8
get_line (UINT32
*length
, CHAR16
*line
, UINT32 line_max
, UINT8 show
)
544 key
= console_get_keystroke();
546 if ((count
>= line_max
&&
547 key
.UnicodeChar
!= CHAR_BACKSPACE
) ||
548 key
.UnicodeChar
== CHAR_NULL
||
549 key
.UnicodeChar
== CHAR_TAB
||
550 key
.UnicodeChar
== CHAR_LINEFEED
||
551 key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
555 if (count
== 0 && key
.UnicodeChar
== CHAR_BACKSPACE
) {
557 } else if (key
.UnicodeChar
== CHAR_BACKSPACE
) {
561 line
[--count
] = '\0';
566 Print(L
"%c", key
.UnicodeChar
);
569 line
[count
++] = key
.UnicodeChar
;
570 } while (key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
578 static EFI_STATUS
compute_pw_hash (void *Data
, UINTN DataSize
, UINT8
*password
,
579 UINT32 pw_length
, UINT8
*hash
)
582 unsigned int ctxsize
;
585 ctxsize
= Sha256GetContextSize();
586 ctx
= AllocatePool(ctxsize
);
589 console_notify(L
"Unable to allocate memory for hash context");
590 return EFI_OUT_OF_RESOURCES
;
593 if (!Sha256Init(ctx
)) {
594 console_notify(L
"Unable to initialise hash");
595 status
= EFI_OUT_OF_RESOURCES
;
599 if (Data
&& DataSize
) {
600 if (!(Sha256Update(ctx
, Data
, DataSize
))) {
601 console_notify(L
"Unable to generate hash");
602 status
= EFI_OUT_OF_RESOURCES
;
607 if (!(Sha256Update(ctx
, password
, pw_length
))) {
608 console_notify(L
"Unable to generate hash");
609 status
= EFI_OUT_OF_RESOURCES
;
613 if (!(Sha256Final(ctx
, hash
))) {
614 console_notify(L
"Unable to finalise hash");
615 status
= EFI_OUT_OF_RESOURCES
;
619 status
= EFI_SUCCESS
;
624 static void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE
*SavedMode
)
627 Print(L
"Invalid parameter: SavedMode\n");
631 CopyMem(SavedMode
, ST
->ConOut
->Mode
, sizeof(SIMPLE_TEXT_OUTPUT_MODE
));
632 uefi_call_wrapper(ST
->ConOut
->EnableCursor
, 2, ST
->ConOut
, FALSE
);
633 uefi_call_wrapper(ST
->ConOut
->SetAttribute
, 2, ST
->ConOut
,
634 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
637 static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE
*SavedMode
)
639 uefi_call_wrapper(ST
->ConOut
->EnableCursor
, 2, ST
->ConOut
,
640 SavedMode
->CursorVisible
);
641 uefi_call_wrapper(ST
->ConOut
->SetCursorPosition
, 3, ST
->ConOut
,
642 SavedMode
->CursorColumn
, SavedMode
->CursorRow
);
643 uefi_call_wrapper(ST
->ConOut
->SetAttribute
, 2, ST
->ConOut
,
644 SavedMode
->Attribute
);
647 static UINT32
get_password (CHAR16
*prompt
, CHAR16
*password
, UINT32 max
)
649 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
656 prompt
= L
"Password:";
658 console_save_and_set_mode(&SavedMode
);
660 str
= PoolPrint(L
"%s ", prompt
);
662 console_errorbox(L
"Failed to allocate prompt");
668 length
= StrLen(message
[0]);
669 console_print_box_at(message
, -1, -length
-4, -5, length
+4, 3, 0, 1);
670 get_line(&pw_length
, password
, max
, 0);
672 console_restore_mode(&SavedMode
);
679 static EFI_STATUS
match_password (PASSWORD_CRYPT
*pw_crypt
,
680 void *Data
, UINTN DataSize
,
681 UINT8
*auth
, CHAR16
*prompt
)
687 CHAR16 password
[PASSWORD_MAX
];
689 UINT8 fail_count
= 0;
693 auth_hash
= pw_crypt
->hash
;
694 auth_size
= get_hash_size (pw_crypt
->method
);
696 return EFI_INVALID_PARAMETER
;
699 auth_size
= SHA256_DIGEST_SIZE
;
701 return EFI_INVALID_PARAMETER
;
704 while (fail_count
< 3) {
705 pw_length
= get_password(prompt
, password
, PASSWORD_MAX
);
707 if (pw_length
< PASSWORD_MIN
|| pw_length
> PASSWORD_MAX
) {
708 console_errorbox(L
"Invalid password length");
714 * Compute password hash
717 char pw_ascii
[PASSWORD_MAX
+ 1];
718 for (i
= 0; i
< pw_length
; i
++)
719 pw_ascii
[i
] = (char)password
[i
];
720 pw_ascii
[pw_length
] = '\0';
722 status
= password_crypt(pw_ascii
, pw_length
, pw_crypt
, hash
);
725 * For backward compatibility
727 status
= compute_pw_hash(Data
, DataSize
, (UINT8
*)password
,
728 pw_length
* sizeof(CHAR16
), hash
);
730 if (status
!= EFI_SUCCESS
) {
731 console_errorbox(L
"Unable to generate password hash");
736 if (CompareMem(auth_hash
, hash
, auth_size
) != 0) {
737 console_errorbox(L
"Password doesn't match");
746 return EFI_ACCESS_DENIED
;
751 static EFI_STATUS
store_keys (void *MokNew
, UINTN MokNewSize
, int authenticate
)
753 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
754 EFI_STATUS efi_status
;
755 UINT8 auth
[PASSWORD_CRYPT_SIZE
];
756 UINTN auth_size
= PASSWORD_CRYPT_SIZE
;
760 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokAuth",
762 &attributes
, &auth_size
, auth
);
764 if (efi_status
!= EFI_SUCCESS
||
765 (auth_size
!= SHA256_DIGEST_SIZE
&&
766 auth_size
!= PASSWORD_CRYPT_SIZE
)) {
767 console_error(L
"Failed to get MokAuth", efi_status
);
771 if (auth_size
== PASSWORD_CRYPT_SIZE
) {
772 efi_status
= match_password((PASSWORD_CRYPT
*)auth
,
773 NULL
, 0, NULL
, NULL
);
775 efi_status
= match_password(NULL
, MokNew
, MokNewSize
,
778 if (efi_status
!= EFI_SUCCESS
)
779 return EFI_ACCESS_DENIED
;
784 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5, L
"MokList",
786 EFI_VARIABLE_NON_VOLATILE
787 | EFI_VARIABLE_BOOTSERVICE_ACCESS
,
791 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5, L
"MokList",
793 EFI_VARIABLE_NON_VOLATILE
794 | EFI_VARIABLE_BOOTSERVICE_ACCESS
795 | EFI_VARIABLE_APPEND_WRITE
,
799 if (efi_status
!= EFI_SUCCESS
) {
800 console_error(L
"Failed to set variable", efi_status
);
807 static UINTN
mok_enrollment_prompt (void *MokNew
, UINTN MokNewSize
, int auth
) {
808 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
809 EFI_STATUS efi_status
;
811 if (list_keys(MokNew
, MokNewSize
, L
"[Enroll MOK]") != EFI_SUCCESS
)
814 if (console_yes_no((CHAR16
*[]){L
"Enroll the key(s)?", NULL
}) == 0)
817 efi_status
= store_keys(MokNew
, MokNewSize
, auth
);
819 if (efi_status
!= EFI_SUCCESS
) {
820 console_notify(L
"Failed to enroll keys\n");
825 LibDeleteVariable(L
"MokNew", &shim_lock_guid
);
826 LibDeleteVariable(L
"MokAuth", &shim_lock_guid
);
828 console_notify(L
"The system must now be rebooted");
829 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
830 EFI_SUCCESS
, 0, NULL
);
831 console_notify(L
"Failed to reboot");
838 static INTN
mok_reset_prompt ()
840 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
841 EFI_STATUS efi_status
;
843 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
845 if (console_yes_no((CHAR16
*[]){L
"Erase all stored keys?", NULL
}) == 0)
848 efi_status
= store_keys(NULL
, 0, TRUE
);
850 if (efi_status
!= EFI_SUCCESS
) {
851 console_notify(L
"Failed to erase keys\n");
855 LibDeleteVariable(L
"MokNew", &shim_lock_guid
);
856 LibDeleteVariable(L
"MokAuth", &shim_lock_guid
);
858 console_notify(L
"The system must now be rebooted");
859 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
860 EFI_SUCCESS
, 0, NULL
);
861 console_notify(L
"Failed to reboot\n");
865 static EFI_STATUS
write_back_mok_list (MokListNode
*list
, INTN key_num
)
867 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
868 EFI_STATUS efi_status
;
869 EFI_SIGNATURE_LIST
*CertList
;
870 EFI_SIGNATURE_DATA
*CertData
;
871 void *Data
= NULL
, *ptr
;
875 for (i
= 0; i
< key_num
; i
++) {
876 if (list
[i
].Mok
== NULL
)
879 DataSize
+= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_GUID
);
880 DataSize
+= list
[i
].MokSize
;
883 Data
= AllocatePool(DataSize
);
884 if (Data
== NULL
&& DataSize
!= 0)
885 return EFI_OUT_OF_RESOURCES
;
889 for (i
= 0; i
< key_num
; i
++) {
890 if (list
[i
].Mok
== NULL
)
893 CertList
= (EFI_SIGNATURE_LIST
*)ptr
;
894 CertData
= (EFI_SIGNATURE_DATA
*)(((uint8_t *)ptr
) +
895 sizeof(EFI_SIGNATURE_LIST
));
897 CertList
->SignatureType
= list
[i
].Type
;
898 CertList
->SignatureListSize
= list
[i
].MokSize
+
899 sizeof(EFI_SIGNATURE_LIST
) +
900 sizeof(EFI_SIGNATURE_DATA
) - 1;
901 CertList
->SignatureHeaderSize
= 0;
902 CertList
->SignatureSize
= list
[i
].MokSize
+ sizeof(EFI_GUID
);
904 CertData
->SignatureOwner
= shim_lock_guid
;
905 CopyMem(CertData
->SignatureData
, list
[i
].Mok
, list
[i
].MokSize
);
907 ptr
= (uint8_t *)ptr
+ sizeof(EFI_SIGNATURE_LIST
) +
908 sizeof(EFI_GUID
) + list
[i
].MokSize
;
911 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5, L
"MokList",
913 EFI_VARIABLE_NON_VOLATILE
914 | EFI_VARIABLE_BOOTSERVICE_ACCESS
,
919 if (efi_status
!= EFI_SUCCESS
) {
920 console_error(L
"Failed to set variable", efi_status
);
927 static EFI_STATUS
delete_keys (void *MokDel
, UINTN MokDelSize
)
929 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
930 EFI_STATUS efi_status
;
931 UINT8 auth
[PASSWORD_CRYPT_SIZE
];
932 UINTN auth_size
= PASSWORD_CRYPT_SIZE
;
934 void *MokListData
= NULL
;
935 UINTN MokListDataSize
= 0;
936 MokListNode
*mok
, *del_key
;
937 INTN mok_num
, del_num
;
940 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokDelAuth",
942 &attributes
, &auth_size
, auth
);
944 if (efi_status
!= EFI_SUCCESS
||
945 (auth_size
!= SHA256_DIGEST_SIZE
&& auth_size
!= PASSWORD_CRYPT_SIZE
)) {
946 console_error(L
"Failed to get MokDelAuth", efi_status
);
950 if (auth_size
== PASSWORD_CRYPT_SIZE
) {
951 efi_status
= match_password((PASSWORD_CRYPT
*)auth
, NULL
, 0,
954 efi_status
= match_password(NULL
, MokDel
, MokDelSize
, auth
, NULL
);
956 if (efi_status
!= EFI_SUCCESS
)
957 return EFI_ACCESS_DENIED
;
959 efi_status
= get_variable(L
"MokList", shim_lock_guid
, &attributes
,
960 &MokListDataSize
, &MokListData
);
962 if (attributes
& EFI_VARIABLE_RUNTIME_ACCESS
) {
963 console_alertbox((CHAR16
*[]){L
"MokList is compromised!",
964 L
"Erase all keys in MokList!",
966 if (LibDeleteVariable(L
"MokList", &shim_lock_guid
) != EFI_SUCCESS
) {
967 console_notify(L
"Failed to erase MokList");
969 return EFI_ACCESS_DENIED
;
973 if (!MokListData
|| MokListDataSize
== 0)
976 /* Construct lists */
977 mok_num
= count_keys(MokListData
, MokListDataSize
);
978 mok
= build_mok_list(mok_num
, MokListData
, MokListDataSize
);
979 del_num
= count_keys(MokDel
, MokDelSize
);
980 del_key
= build_mok_list(del_num
, MokDel
, MokDelSize
);
982 /* Search and destroy */
983 for (i
= 0; i
< del_num
; i
++) {
984 UINT32 key_size
= del_key
[i
].MokSize
;
985 void *key
= del_key
[i
].Mok
;
986 for (j
= 0; j
< mok_num
; j
++) {
987 if (mok
[j
].MokSize
== key_size
&&
988 CompareMem(key
, mok
[j
].Mok
, key_size
) == 0) {
996 efi_status
= write_back_mok_list(mok
, mok_num
);
999 FreePool(MokListData
);
1008 static INTN
mok_deletion_prompt (void *MokDel
, UINTN MokDelSize
)
1010 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1011 EFI_STATUS efi_status
;
1013 if (list_keys(MokDel
, MokDelSize
, L
"[Delete MOK]") != EFI_SUCCESS
) {
1017 if (console_yes_no((CHAR16
*[]){L
"Delete the key(s)?", NULL
}) == 0)
1020 efi_status
= delete_keys(MokDel
, MokDelSize
);
1022 if (efi_status
!= EFI_SUCCESS
) {
1023 console_notify(L
"Failed to delete keys");
1027 LibDeleteVariable(L
"MokDel", &shim_lock_guid
);
1028 LibDeleteVariable(L
"MokDelAuth", &shim_lock_guid
);
1030 console_notify(L
"The system must now be rebooted");
1031 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
1032 EFI_SUCCESS
, 0, NULL
);
1033 console_notify(L
"Failed to reboot");
1037 static INTN
mok_sb_prompt (void *MokSB
, UINTN MokSBSize
) {
1038 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1039 EFI_STATUS efi_status
;
1040 MokSBvar
*var
= MokSB
;
1041 CHAR16 pass1
, pass2
, pass3
;
1042 UINT8 fail_count
= 0;
1045 UINT8 pos1
, pos2
, pos3
;
1048 if (MokSBSize
!= sizeof(MokSBvar
)) {
1049 console_notify(L
"Invalid MokSB variable contents");
1053 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
1055 while (fail_count
< 3) {
1056 RandomBytes (&pos1
, sizeof(pos1
));
1057 pos1
= (pos1
% var
->PWLen
);
1060 RandomBytes (&pos2
, sizeof(pos2
));
1061 pos2
= (pos2
% var
->PWLen
);
1062 } while (pos2
== pos1
);
1065 RandomBytes (&pos3
, sizeof(pos3
));
1066 pos3
= (pos3
% var
->PWLen
) ;
1067 } while (pos3
== pos2
|| pos3
== pos1
);
1069 Print(L
"Enter password character %d: ", pos1
+ 1);
1070 get_line(&length
, &pass1
, 1, 0);
1072 Print(L
"Enter password character %d: ", pos2
+ 1);
1073 get_line(&length
, &pass2
, 1, 0);
1075 Print(L
"Enter password character %d: ", pos3
+ 1);
1076 get_line(&length
, &pass3
, 1, 0);
1078 if (pass1
!= var
->Password
[pos1
] ||
1079 pass2
!= var
->Password
[pos2
] ||
1080 pass3
!= var
->Password
[pos3
]) {
1081 Print(L
"Invalid character\n");
1088 if (fail_count
>= 3) {
1089 console_notify(L
"Password limit reached");
1093 if (var
->MokSBState
== 0)
1094 ret
= console_yes_no((CHAR16
*[]){L
"Disable Secure Boot", NULL
});
1096 ret
= console_yes_no((CHAR16
*[]){L
"Enable Secure Boot", NULL
});
1099 LibDeleteVariable(L
"MokSB", &shim_lock_guid
);
1103 if (var
->MokSBState
== 0) {
1104 efi_status
= uefi_call_wrapper(RT
->SetVariable
,
1107 EFI_VARIABLE_NON_VOLATILE
|
1108 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1110 if (efi_status
!= EFI_SUCCESS
) {
1111 console_notify(L
"Failed to set Secure Boot state");
1115 LibDeleteVariable(L
"MokSBState", &shim_lock_guid
);
1118 console_notify(L
"The system must now be rebooted");
1119 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
,
1120 EFI_SUCCESS
, 0, NULL
);
1121 console_notify(L
"Failed to reboot");
1125 static INTN
mok_pw_prompt (void *MokPW
, UINTN MokPWSize
) {
1126 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1127 EFI_STATUS efi_status
;
1128 UINT8 hash
[PASSWORD_CRYPT_SIZE
];
1131 if (MokPWSize
!= SHA256_DIGEST_SIZE
&& MokPWSize
!= PASSWORD_CRYPT_SIZE
) {
1132 console_notify(L
"Invalid MokPW variable contents");
1136 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
1138 SetMem(hash
, PASSWORD_CRYPT_SIZE
, 0);
1140 if (MokPWSize
== PASSWORD_CRYPT_SIZE
) {
1141 if (CompareMem(MokPW
, hash
, PASSWORD_CRYPT_SIZE
) == 0)
1144 if (CompareMem(MokPW
, hash
, SHA256_DIGEST_SIZE
) == 0)
1149 if (console_yes_no((CHAR16
*[]){L
"Clear MOK password?", NULL
}) == 0)
1152 LibDeleteVariable(L
"MokPWStore", &shim_lock_guid
);
1153 LibDeleteVariable(L
"MokPW", &shim_lock_guid
);
1157 if (MokPWSize
== PASSWORD_CRYPT_SIZE
) {
1158 efi_status
= match_password((PASSWORD_CRYPT
*)MokPW
, NULL
, 0,
1159 NULL
, L
"Confirm MOK passphrase: ");
1161 efi_status
= match_password(NULL
, NULL
, 0, MokPW
,
1162 L
"Confirm MOK passphrase: ");
1165 if (efi_status
!= EFI_SUCCESS
) {
1166 console_notify(L
"Password limit reached");
1170 if (console_yes_no((CHAR16
*[]){L
"Set MOK password?", NULL
}) == 0)
1173 efi_status
= uefi_call_wrapper(RT
->SetVariable
, 5,
1176 EFI_VARIABLE_NON_VOLATILE
|
1177 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
1179 if (efi_status
!= EFI_SUCCESS
) {
1180 console_notify(L
"Failed to set MOK password");
1184 LibDeleteVariable(L
"MokPW", &shim_lock_guid
);
1186 console_notify(L
"The system must now be rebooted");
1187 uefi_call_wrapper(RT
->ResetSystem
, 4, EfiResetWarm
, EFI_SUCCESS
, 0,
1189 console_notify(L
"Failed to reboot");
1193 static UINTN
verify_certificate(void *cert
, UINTN size
)
1196 if (!cert
|| size
== 0)
1199 if (!(X509ConstructCertificate(cert
, size
, (UINT8
**) &X509Cert
)) ||
1201 console_notify(L
"Invalid X509 certificate");
1205 X509_free(X509Cert
);
1209 static EFI_STATUS
enroll_file (void *data
, UINTN datasize
, BOOLEAN hash
)
1211 EFI_STATUS status
= EFI_SUCCESS
;
1212 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1213 EFI_SIGNATURE_LIST
*CertList
;
1214 EFI_SIGNATURE_DATA
*CertData
;
1215 UINTN mokbuffersize
;
1216 void *mokbuffer
= NULL
;
1219 UINT8 sha256
[SHA256_DIGEST_SIZE
];
1220 UINT8 sha1
[SHA1_DIGEST_SIZE
];
1221 SHIM_LOCK
*shim_lock
;
1222 EFI_GUID shim_guid
= SHIM_LOCK_GUID
;
1223 PE_COFF_LOADER_IMAGE_CONTEXT context
;
1225 status
= LibLocateProtocol(&shim_guid
, (VOID
**)&shim_lock
);
1227 if (status
!= EFI_SUCCESS
)
1230 mokbuffersize
= sizeof(EFI_SIGNATURE_LIST
) + sizeof(EFI_GUID
) +
1233 mokbuffer
= AllocatePool(mokbuffersize
);
1238 status
= shim_lock
->Context(data
, datasize
, &context
);
1240 if (status
!= EFI_SUCCESS
)
1243 status
= shim_lock
->Hash(data
, datasize
, &context
, sha256
,
1246 if (status
!= EFI_SUCCESS
)
1249 CertList
= mokbuffer
;
1250 CertList
->SignatureType
= EfiHashSha256Guid
;
1251 CertList
->SignatureSize
= 16 + SHA256_DIGEST_SIZE
;
1252 CertData
= (EFI_SIGNATURE_DATA
*)(((UINT8
*)mokbuffer
) +
1253 sizeof(EFI_SIGNATURE_LIST
));
1254 CopyMem(CertData
->SignatureData
, sha256
, SHA256_DIGEST_SIZE
);
1256 mokbuffersize
= datasize
+ sizeof(EFI_SIGNATURE_LIST
) +
1258 mokbuffer
= AllocatePool(mokbuffersize
);
1263 CertList
= mokbuffer
;
1264 CertList
->SignatureType
= EfiCertX509Guid
;
1265 CertList
->SignatureSize
= 16 + datasize
;
1267 memcpy(mokbuffer
+ sizeof(EFI_SIGNATURE_LIST
) + 16, data
,
1270 CertData
= (EFI_SIGNATURE_DATA
*)(((UINT8
*)mokbuffer
) +
1271 sizeof(EFI_SIGNATURE_LIST
));
1274 CertList
->SignatureListSize
= mokbuffersize
;
1275 CertList
->SignatureHeaderSize
= 0;
1276 CertData
->SignatureOwner
= shim_lock_guid
;
1279 if (!verify_certificate(CertData
->SignatureData
, datasize
))
1283 mok_enrollment_prompt(mokbuffer
, mokbuffersize
, FALSE
);
1286 FreePool(mokbuffer
);
1291 static void mok_hash_enroll(void)
1293 EFI_STATUS efi_status
;
1294 CHAR16
*file_name
= NULL
;
1295 EFI_HANDLE im
= NULL
;
1296 EFI_FILE
*file
= NULL
;
1300 simple_file_selector(&im
, (CHAR16
*[]){
1303 L
"The Selected Binary will have its hash Enrolled",
1304 L
"This means it will Subsequently Boot with no prompting",
1305 L
"Remember to make sure it is a genuine binary before Enroling its hash",
1307 }, L
"\\", L
"", &file_name
);
1312 efi_status
= simple_file_open(im
, file_name
, &file
, EFI_FILE_MODE_READ
);
1314 if (efi_status
!= EFI_SUCCESS
) {
1315 console_error(L
"Unable to open file", efi_status
);
1319 simple_file_read_all(file
, &filesize
, &data
);
1320 simple_file_close(file
);
1323 console_error(L
"Unable to read file", efi_status
);
1327 efi_status
= enroll_file(data
, filesize
, TRUE
);
1329 if (efi_status
!= EFI_SUCCESS
)
1330 console_error(L
"Hash failed (did you select a valid EFI binary?)", efi_status
);
1335 static void mok_key_enroll(void)
1337 EFI_STATUS efi_status
;
1338 CHAR16
*file_name
= NULL
;
1339 EFI_HANDLE im
= NULL
;
1340 EFI_FILE
*file
= NULL
;
1344 simple_file_selector(&im
, (CHAR16
*[]){
1347 L
"The selected key will be enrolled into the MOK database",
1348 L
"This means any binaries signed with it will be run without prompting",
1349 L
"Remember to make sure it is a genuine key before Enroling it",
1351 }, L
"\\", L
"", &file_name
);
1356 efi_status
= simple_file_open(im
, file_name
, &file
, EFI_FILE_MODE_READ
);
1358 if (efi_status
!= EFI_SUCCESS
) {
1359 console_error(L
"Unable to open file", efi_status
);
1363 simple_file_read_all(file
, &filesize
, &data
);
1364 simple_file_close(file
);
1367 console_error(L
"Unable to read file", efi_status
);
1371 enroll_file(data
, filesize
, FALSE
);
1375 static BOOLEAN
verify_pw(BOOLEAN
*protected)
1377 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1378 EFI_STATUS efi_status
;
1379 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
1380 UINT8 pwhash
[PASSWORD_CRYPT_SIZE
];
1381 UINTN size
= PASSWORD_CRYPT_SIZE
;
1387 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokPWStore",
1388 &shim_lock_guid
, &attributes
, &size
,
1392 * If anything can attack the password it could just set it to a
1393 * known value, so there's no safety advantage in failing to validate
1394 * purely because of a failure to read the variable
1396 if (efi_status
!= EFI_SUCCESS
||
1397 (size
!= SHA256_DIGEST_SIZE
&& size
!= PASSWORD_CRYPT_SIZE
))
1400 if (attributes
& EFI_VARIABLE_RUNTIME_ACCESS
)
1403 uefi_call_wrapper(ST
->ConOut
->ClearScreen
, 1, ST
->ConOut
);
1405 /* Draw the background */
1406 console_save_and_set_mode(&SavedMode
);
1407 message
[0] = PoolPrint (L
"%s UEFI key management", SHIM_VENDOR
);
1409 console_print_box_at(message
, -1, 0, 0, -1, -1, 1, 1);
1410 FreePool(message
[0]);
1411 console_restore_mode(&SavedMode
);
1413 if (size
== PASSWORD_CRYPT_SIZE
) {
1414 efi_status
= match_password((PASSWORD_CRYPT
*)pwhash
, NULL
, 0,
1415 NULL
, L
"Enter MOK password:");
1417 efi_status
= match_password(NULL
, NULL
, 0, pwhash
,
1418 L
"Enter MOK password:");
1420 if (efi_status
!= EFI_SUCCESS
) {
1421 console_notify(L
"Password limit reached");
1430 static int draw_countdown()
1432 SIMPLE_TEXT_OUTPUT_MODE SavedMode
;
1437 CHAR16
*message
= L
"Press any key to perform MOK management";
1438 int timeout
= 10, wait
= 10000000;
1440 console_save_and_set_mode (&SavedMode
);
1442 title
[0] = PoolPrint (L
"%s UEFI key management", SHIM_VENDOR
);
1445 console_print_box_at(title
, -1, 0, 0, -1, -1, 1, 1);
1447 uefi_call_wrapper(ST
->ConOut
->QueryMode
, 4, ST
->ConOut
,
1448 ST
->ConOut
->Mode
->Mode
, &cols
, &rows
);
1450 PrintAt((cols
- StrLen(message
))/2, rows
/2, message
);
1453 PrintAt(2, rows
- 3, L
"Booting in %d seconds ", timeout
);
1455 PrintAt(2, rows
- 3, L
"Booting in %d second ", timeout
);
1457 status
= WaitForSingleEvent(ST
->ConIn
->WaitForKey
, wait
);
1459 if (status
!= EFI_TIMEOUT
) {
1460 /* Clear the key in the queue */
1461 uefi_call_wrapper(ST
->ConIn
->ReadKeyStroke
, 2,
1473 console_restore_mode(&SavedMode
);
1489 static EFI_STATUS
enter_mok_menu(EFI_HANDLE image_handle
,
1490 void *MokNew
, UINTN MokNewSize
,
1491 void *MokDel
, UINTN MokDelSize
,
1492 void *MokSB
, UINTN MokSBSize
,
1493 void *MokPW
, UINTN MokPWSize
)
1495 CHAR16
**menu_strings
;
1496 mok_menu_item
*menu_item
;
1499 UINT32 MokDelAuth
= 0;
1500 UINTN menucount
= 3, i
= 0;
1501 EFI_STATUS efi_status
;
1502 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1503 UINT8 auth
[PASSWORD_CRYPT_SIZE
];
1504 UINTN auth_size
= PASSWORD_CRYPT_SIZE
;
1507 EFI_STATUS ret
= EFI_SUCCESS
;
1509 if (verify_pw(&protected) == FALSE
)
1510 return EFI_ACCESS_DENIED
;
1512 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokAuth",
1514 &attributes
, &auth_size
, auth
);
1516 if ((efi_status
== EFI_SUCCESS
) &&
1517 (auth_size
== SHA256_DIGEST_SIZE
|| auth_size
== PASSWORD_CRYPT_SIZE
))
1520 efi_status
= uefi_call_wrapper(RT
->GetVariable
, 5, L
"MokDelAuth",
1522 &attributes
, &auth_size
, auth
);
1524 if ((efi_status
== EFI_SUCCESS
) &&
1525 (auth_size
== SHA256_DIGEST_SIZE
|| auth_size
== PASSWORD_CRYPT_SIZE
))
1528 if (MokNew
|| MokAuth
)
1531 if (MokDel
|| MokDelAuth
)
1540 menu_strings
= AllocateZeroPool(sizeof(CHAR16
*) * (menucount
+ 1));
1543 return EFI_OUT_OF_RESOURCES
;
1545 menu_item
= AllocateZeroPool(sizeof(mok_menu_item
) * menucount
);
1548 FreePool(menu_strings
);
1549 return EFI_OUT_OF_RESOURCES
;
1552 menu_strings
[i
] = L
"Continue boot";
1553 menu_item
[i
] = MOK_CONTINUE_BOOT
;
1557 if (MokNew
|| MokAuth
) {
1559 menu_strings
[i
] = L
"Reset MOK";
1560 menu_item
[i
] = MOK_RESET_MOK
;
1562 menu_strings
[i
] = L
"Enroll MOK";
1563 menu_item
[i
] = MOK_ENROLL_MOK
;
1568 if (MokDel
|| MokDelAuth
) {
1569 menu_strings
[i
] = L
"Delete MOK";
1570 menu_item
[i
] = MOK_DELETE_MOK
;
1575 menu_strings
[i
] = L
"Change Secure Boot state";
1576 menu_item
[i
] = MOK_CHANGE_SB
;
1581 menu_strings
[i
] = L
"Set MOK password";
1582 menu_item
[i
] = MOK_SET_PW
;
1586 menu_strings
[i
] = L
"Enroll key from disk";
1587 menu_item
[i
] = MOK_KEY_ENROLL
;
1590 menu_strings
[i
] = L
"Enroll hash from disk";
1591 menu_item
[i
] = MOK_HASH_ENROLL
;
1594 menu_strings
[i
] = NULL
;
1596 if (protected == FALSE
&& draw_countdown() == 0)
1599 while (choice
>= 0) {
1600 choice
= console_select((CHAR16
*[]){ L
"Perform MOK management", NULL
},
1606 switch (menu_item
[choice
]) {
1607 case MOK_CONTINUE_BOOT
:
1612 case MOK_ENROLL_MOK
:
1613 mok_enrollment_prompt(MokNew
, MokNewSize
, TRUE
);
1615 case MOK_DELETE_MOK
:
1616 mok_deletion_prompt(MokDel
, MokDelSize
);
1619 mok_sb_prompt(MokSB
, MokSBSize
);
1622 mok_pw_prompt(MokPW
, MokPWSize
);
1624 case MOK_KEY_ENROLL
:
1627 case MOK_HASH_ENROLL
:
1636 FreePool(menu_strings
);
1639 FreePool(menu_item
);
1644 static EFI_STATUS
check_mok_request(EFI_HANDLE image_handle
)
1646 EFI_GUID shim_lock_guid
= SHIM_LOCK_GUID
;
1647 UINTN MokNewSize
= 0, MokDelSize
= 0, MokSBSize
= 0, MokPWSize
= 0;
1648 void *MokNew
= NULL
;
1649 void *MokDel
= NULL
;
1653 MokNew
= LibGetVariableAndSize(L
"MokNew", &shim_lock_guid
, &MokNewSize
);
1655 MokDel
= LibGetVariableAndSize(L
"MokDel", &shim_lock_guid
, &MokDelSize
);
1657 MokSB
= LibGetVariableAndSize(L
"MokSB", &shim_lock_guid
, &MokSBSize
);
1659 MokPW
= LibGetVariableAndSize(L
"MokPW", &shim_lock_guid
, &MokPWSize
);
1661 enter_mok_menu(image_handle
, MokNew
, MokNewSize
, MokDel
, MokDelSize
,
1662 MokSB
, MokSBSize
, MokPW
, MokPWSize
);
1665 if (LibDeleteVariable(L
"MokNew", &shim_lock_guid
) != EFI_SUCCESS
) {
1666 console_notify(L
"Failed to delete MokNew");
1672 if (LibDeleteVariable(L
"MokDel", &shim_lock_guid
) != EFI_SUCCESS
) {
1673 console_notify(L
"Failed to delete MokDel");
1679 if (LibDeleteVariable(L
"MokSB", &shim_lock_guid
) != EFI_SUCCESS
) {
1680 console_notify(L
"Failed to delete MokSB");
1686 if (LibDeleteVariable(L
"MokPW", &shim_lock_guid
) != EFI_SUCCESS
) {
1687 console_notify(L
"Failed to delete MokPW");
1692 LibDeleteVariable(L
"MokAuth", &shim_lock_guid
);
1693 LibDeleteVariable(L
"MokDelAuth", &shim_lock_guid
);
1698 static VOID
setup_console (int text
)
1701 EFI_GUID console_control_guid
= EFI_CONSOLE_CONTROL_PROTOCOL_GUID
;
1702 EFI_CONSOLE_CONTROL_PROTOCOL
*concon
;
1703 static EFI_CONSOLE_CONTROL_SCREEN_MODE mode
=
1704 EfiConsoleControlScreenGraphics
;
1705 EFI_CONSOLE_CONTROL_SCREEN_MODE new_mode
;
1707 status
= LibLocateProtocol(&console_control_guid
, (VOID
**)&concon
);
1708 if (status
!= EFI_SUCCESS
)
1712 new_mode
= EfiConsoleControlScreenText
;
1714 status
= uefi_call_wrapper(concon
->GetMode
, 4, concon
, &mode
,
1716 /* If that didn't work, assume it's graphics */
1717 if (status
!= EFI_SUCCESS
)
1718 mode
= EfiConsoleControlScreenGraphics
;
1723 uefi_call_wrapper(concon
->SetMode
, 2, concon
, new_mode
);
1726 static EFI_STATUS
setup_rand (void)
1729 EFI_STATUS efi_status
;
1733 efi_status
= uefi_call_wrapper(RT
->GetTime
, 2, &time
, NULL
);
1735 if (efi_status
!= EFI_SUCCESS
)
1738 seed
= ((UINT64
)time
.Year
<< 48) | ((UINT64
)time
.Month
<< 40) |
1739 ((UINT64
)time
.Day
<< 32) | ((UINT64
)time
.Hour
<< 24) |
1740 ((UINT64
)time
.Minute
<< 16) | ((UINT64
)time
.Second
<< 8) |
1741 ((UINT64
)time
.Daylight
);
1743 status
= RandomSeed((UINT8
*)&seed
, sizeof(seed
));
1751 EFI_STATUS
efi_main (EFI_HANDLE image_handle
, EFI_SYSTEM_TABLE
*systab
)
1753 EFI_STATUS efi_status
;
1755 InitializeLib(image_handle
, systab
);
1761 efi_status
= check_mok_request(image_handle
);