41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
1 |
#include <efi.h> |
2 |
#include <efilib.h> |
|
3 |
#include <Library/BaseCryptLib.h> |
|
4 |
#include <openssl/x509.h> |
|
5 |
#include "shim.h" |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
6 |
#include "PeImage.h" |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
7 |
#include "PasswordCrypt.h" |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
8 |
|
41.2.152
by Gary Ching-Pang Lin
Merge signature.h into efiauthenticated.h and guid.h |
9 |
#include "guid.h" |
10 |
#include "console.h" |
|
41.2.153
by Gary Ching-Pang Lin
Merge variable retrieving functions |
11 |
#include "variables.h" |
41.2.152
by Gary Ching-Pang Lin
Merge signature.h into efiauthenticated.h and guid.h |
12 |
#include "simple_file.h" |
13 |
#include "efiauthenticated.h" |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
14 |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
15 |
#define PASSWORD_MAX 256
|
16 |
#define PASSWORD_MIN 1
|
|
17 |
#define SB_PASSWORD_LEN 16
|
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
18 |
|
41.2.146
by Gary Ching-Pang Lin
MokManager: fetch more info from X509 name |
19 |
#define NAME_LINE_MAX 70
|
20 |
||
41.2.52
by Matthew Garrett
Add menu header |
21 |
#ifndef SHIM_VENDOR
|
22 |
#define SHIM_VENDOR L"Shim"
|
|
23 |
#endif
|
|
24 |
||
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
25 |
#define EFI_VARIABLE_APPEND_WRITE 0x00000040
|
26 |
||
41.2.121
by Peter Jones
We have to declare SHIM_LOCK_GUID here as well. |
27 |
EFI_GUID SHIM_LOCK_GUID = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }; |
28 |
||
41.3.1
by Matthew Garrett
Add section headers |
29 |
#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
|
30 |
#define HASH_STRING L"Select a file to trust:\n\n"
|
|
31 |
||
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
32 |
struct menu_item { |
33 |
CHAR16 *text; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
34 |
INTN (* callback)(void *data, void *data2, void *data3); |
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
35 |
void *data; |
36 |
void *data2; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
37 |
void *data3; |
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
38 |
UINTN colour; |
39 |
};
|
|
40 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
41 |
typedef struct { |
42 |
UINT32 MokSize; |
|
43 |
UINT8 *Mok; |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
44 |
EFI_GUID Type; |
41.2.41
by Matthew Garrett
Add __attribute__ ((packed)) to MokListNode definition |
45 |
} __attribute__ ((packed)) MokListNode; |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
46 |
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
47 |
typedef struct { |
48 |
UINT32 MokSBState; |
|
41.3.12
by Matthew Garrett
Update image validation enable/disable |
49 |
UINT32 PWLen; |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
50 |
CHAR16 Password[SB_PASSWORD_LEN]; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
51 |
} __attribute__ ((packed)) MokSBvar; |
52 |
||
41.2.171
by Josh Boyer
Add support for disabling db for verification |
53 |
typedef struct { |
54 |
UINT32 MokDBState; |
|
55 |
UINT32 PWLen; |
|
56 |
CHAR16 Password[SB_PASSWORD_LEN]; |
|
57 |
} __attribute__ ((packed)) MokDBvar; |
|
58 |
||
41.2.29
by Gary Ching-Pang Lin
Calculate SHA1 fingerprint |
59 |
static EFI_STATUS get_sha1sum (void *Data, int DataSize, UINT8 *hash) |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
60 |
{
|
61 |
EFI_STATUS status; |
|
62 |
unsigned int ctxsize; |
|
63 |
void *ctx = NULL; |
|
64 |
||
41.2.29
by Gary Ching-Pang Lin
Calculate SHA1 fingerprint |
65 |
ctxsize = Sha1GetContextSize(); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
66 |
ctx = AllocatePool(ctxsize); |
67 |
||
68 |
if (!ctx) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
69 |
console_notify(L"Unable to allocate memory for hash context"); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
70 |
return EFI_OUT_OF_RESOURCES; |
71 |
}
|
|
72 |
||
41.2.29
by Gary Ching-Pang Lin
Calculate SHA1 fingerprint |
73 |
if (!Sha1Init(ctx)) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
74 |
console_notify(L"Unable to initialise hash"); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
75 |
status = EFI_OUT_OF_RESOURCES; |
76 |
goto done; |
|
77 |
}
|
|
78 |
||
41.2.29
by Gary Ching-Pang Lin
Calculate SHA1 fingerprint |
79 |
if (!(Sha1Update(ctx, Data, DataSize))) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
80 |
console_notify(L"Unable to generate hash"); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
81 |
status = EFI_OUT_OF_RESOURCES; |
82 |
goto done; |
|
83 |
}
|
|
84 |
||
41.2.29
by Gary Ching-Pang Lin
Calculate SHA1 fingerprint |
85 |
if (!(Sha1Final(ctx, hash))) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
86 |
console_notify(L"Unable to finalise hash"); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
87 |
status = EFI_OUT_OF_RESOURCES; |
88 |
goto done; |
|
89 |
}
|
|
90 |
||
91 |
status = EFI_SUCCESS; |
|
92 |
done: |
|
93 |
return status; |
|
94 |
}
|
|
95 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
96 |
static UINT32 count_keys(void *Data, UINTN DataSize) |
97 |
{
|
|
98 |
EFI_SIGNATURE_LIST *CertList = Data; |
|
41.2.152
by Gary Ching-Pang Lin
Merge signature.h into efiauthenticated.h and guid.h |
99 |
EFI_GUID CertType = X509_GUID; |
100 |
EFI_GUID HashType = EFI_CERT_SHA256_GUID; |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
101 |
UINTN dbsize = DataSize; |
102 |
UINT32 MokNum = 0; |
|
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
103 |
void *end = Data + DataSize; |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
104 |
|
105 |
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { |
|
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
106 |
|
107 |
/* Use ptr arithmetics to ensure bounded access. Do not allow 0
|
|
108 |
* SignatureListSize that will cause endless loop.
|
|
109 |
*/
|
|
110 |
if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) { |
|
111 |
console_notify(L"Invalid MOK detected! Ignoring MOK List."); |
|
112 |
return 0; |
|
113 |
}
|
|
114 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
115 |
if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && |
116 |
(CompareGuid (&CertList->SignatureType, &HashType) != 0)) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
117 |
console_notify(L"Doesn't look like a key or hash"); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
118 |
dbsize -= CertList->SignatureListSize; |
119 |
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + |
|
120 |
CertList->SignatureListSize); |
|
121 |
continue; |
|
122 |
}
|
|
123 |
||
124 |
if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && |
|
125 |
(CertList->SignatureSize != 48)) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
126 |
console_notify(L"Doesn't look like a valid hash"); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
127 |
dbsize -= CertList->SignatureListSize; |
128 |
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + |
|
129 |
CertList->SignatureListSize); |
|
130 |
continue; |
|
131 |
}
|
|
132 |
||
133 |
MokNum++; |
|
134 |
dbsize -= CertList->SignatureListSize; |
|
135 |
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + |
|
136 |
CertList->SignatureListSize); |
|
137 |
}
|
|
138 |
||
139 |
return MokNum; |
|
140 |
}
|
|
141 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
142 |
static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { |
143 |
MokListNode *list; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
144 |
EFI_SIGNATURE_LIST *CertList = Data; |
145 |
EFI_SIGNATURE_DATA *Cert; |
|
41.2.152
by Gary Ching-Pang Lin
Merge signature.h into efiauthenticated.h and guid.h |
146 |
EFI_GUID CertType = X509_GUID; |
147 |
EFI_GUID HashType = EFI_CERT_SHA256_GUID; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
148 |
UINTN dbsize = DataSize; |
149 |
UINTN count = 0; |
|
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
150 |
void *end = Data + DataSize; |
41.2.19
by Gary Ching-Pang Lin
Make sure the variables are not broken |
151 |
|
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
152 |
list = AllocatePool(sizeof(MokListNode) * num); |
153 |
||
154 |
if (!list) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
155 |
console_notify(L"Unable to allocate MOK list"); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
156 |
return NULL; |
157 |
}
|
|
158 |
||
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
159 |
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { |
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
160 |
/* CertList out of bounds? */
|
161 |
if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) { |
|
162 |
FreePool(list); |
|
163 |
return NULL; |
|
164 |
}
|
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
165 |
if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && |
166 |
(CompareGuid (&CertList->SignatureType, &HashType) != 0)) { |
|
167 |
dbsize -= CertList->SignatureListSize; |
|
168 |
CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList + |
|
41.3.9
by Matthew Garrett
Fix key database parsing |
169 |
CertList->SignatureListSize); |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
170 |
continue; |
171 |
}
|
|
172 |
||
173 |
if ((CompareGuid (&CertList->SignatureType, &HashType) == 0) && |
|
174 |
(CertList->SignatureSize != 48)) { |
|
175 |
dbsize -= CertList->SignatureListSize; |
|
176 |
CertList = (EFI_SIGNATURE_LIST *)((UINT8 *) CertList + |
|
41.3.9
by Matthew Garrett
Fix key database parsing |
177 |
CertList->SignatureListSize); |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
178 |
continue; |
179 |
}
|
|
180 |
||
181 |
Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) + |
|
182 |
sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); |
|
183 |
||
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
184 |
/* Cert out of bounds? */
|
185 |
if ((void *)(Cert + 1) > end || CertList->SignatureSize <= sizeof(EFI_GUID)) { |
|
186 |
FreePool(list); |
|
187 |
return NULL; |
|
188 |
}
|
|
189 |
||
41.2.70
by Gary Ching-Pang Lin
MOK doesn't include the signature owner |
190 |
list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID); |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
191 |
list[count].Mok = (void *)Cert->SignatureData; |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
192 |
list[count].Type = CertList->SignatureType; |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
193 |
|
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
194 |
/* MOK out of bounds? */
|
41.2.263
by Peter Jones
Make another integer compare be signed/unsigned safe as well. |
195 |
if (list[count].MokSize > (unsigned long)end - |
196 |
(unsigned long)list[count].Mok) { |
|
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
197 |
FreePool(list); |
198 |
return NULL; |
|
199 |
}
|
|
200 |
||
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
201 |
count++; |
202 |
dbsize -= CertList->SignatureListSize; |
|
203 |
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + |
|
41.3.9
by Matthew Garrett
Fix key database parsing |
204 |
CertList->SignatureListSize); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
205 |
}
|
206 |
||
207 |
return list; |
|
208 |
}
|
|
209 |
||
41.2.146
by Gary Ching-Pang Lin
MokManager: fetch more info from X509 name |
210 |
typedef struct { |
211 |
int nid; |
|
212 |
CHAR16 *name; |
|
213 |
} NidName; |
|
214 |
||
215 |
static NidName nidname[] = { |
|
216 |
{NID_commonName, L"CN"}, |
|
217 |
{NID_organizationName, L"O"}, |
|
218 |
{NID_countryName, L"C"}, |
|
219 |
{NID_stateOrProvinceName, L"ST"}, |
|
220 |
{NID_localityName, L"L"}, |
|
221 |
{-1, NULL} |
|
222 |
};
|
|
223 |
||
224 |
static CHAR16* get_x509_name (X509_NAME *X509Name) |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
225 |
{
|
41.2.146
by Gary Ching-Pang Lin
MokManager: fetch more info from X509 name |
226 |
CHAR16 name[NAME_LINE_MAX+1]; |
227 |
CHAR16 part[NAME_LINE_MAX+1]; |
|
228 |
char str[NAME_LINE_MAX]; |
|
229 |
int i, len, rest, first; |
|
230 |
||
231 |
name[0] = '\0'; |
|
232 |
rest = NAME_LINE_MAX; |
|
233 |
first = 1; |
|
234 |
for (i = 0; nidname[i].name != NULL; i++) { |
|
235 |
int add; |
|
236 |
len = X509_NAME_get_text_by_NID (X509Name, nidname[i].nid, |
|
237 |
str, NAME_LINE_MAX); |
|
238 |
if (len <= 0) |
|
239 |
continue; |
|
240 |
||
241 |
if (first) |
|
242 |
add = len + (int)StrLen(nidname[i].name) + 1; |
|
243 |
else
|
|
244 |
add = len + (int)StrLen(nidname[i].name) + 3; |
|
245 |
||
246 |
if (add > rest) |
|
247 |
continue; |
|
248 |
||
249 |
if (first) { |
|
250 |
SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L"%s=%a", |
|
251 |
nidname[i].name, str); |
|
252 |
} else { |
|
253 |
SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L", %s=%a", |
|
254 |
nidname[i].name, str); |
|
255 |
}
|
|
256 |
StrCat(name, part); |
|
257 |
rest -= add; |
|
258 |
first = 0; |
|
259 |
}
|
|
260 |
||
261 |
if (rest >= 0 && rest < NAME_LINE_MAX) |
|
262 |
return PoolPrint(L"%s", name); |
|
263 |
||
264 |
return NULL; |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
265 |
}
|
266 |
||
267 |
static CHAR16* get_x509_time (ASN1_TIME *time) |
|
268 |
{
|
|
269 |
BIO *bio = BIO_new (BIO_s_mem()); |
|
270 |
char str[30]; |
|
271 |
int len; |
|
272 |
||
273 |
ASN1_TIME_print (bio, time); |
|
274 |
len = BIO_read(bio, str, 29); |
|
275 |
if (len < 0) |
|
276 |
len = 0; |
|
277 |
str[len] = '\0'; |
|
278 |
BIO_free (bio); |
|
279 |
||
280 |
return PoolPrint(L"%a", str); |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
281 |
}
|
282 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
283 |
static void show_x509_info (X509 *X509Cert, UINT8 *hash) |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
284 |
{
|
41.2.14
by Gary Ching-Pang Lin
Improve the layout of the key info |
285 |
ASN1_INTEGER *serial; |
286 |
BIGNUM *bnser; |
|
287 |
unsigned char hexbuf[30]; |
|
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
288 |
X509_NAME *X509Name; |
289 |
ASN1_TIME *time; |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
290 |
CHAR16 *issuer = NULL; |
291 |
CHAR16 *subject = NULL; |
|
292 |
CHAR16 *from = NULL; |
|
293 |
CHAR16 *until = NULL; |
|
294 |
POOL_PRINT hash_string1; |
|
295 |
POOL_PRINT hash_string2; |
|
296 |
POOL_PRINT serial_string; |
|
297 |
int fields = 0; |
|
298 |
CHAR16 **text; |
|
299 |
int i = 0; |
|
300 |
||
301 |
ZeroMem(&hash_string1, sizeof(hash_string1)); |
|
302 |
ZeroMem(&hash_string2, sizeof(hash_string2)); |
|
303 |
ZeroMem(&serial_string, sizeof(serial_string)); |
|
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
304 |
|
41.2.14
by Gary Ching-Pang Lin
Improve the layout of the key info |
305 |
serial = X509_get_serialNumber(X509Cert); |
306 |
if (serial) { |
|
307 |
int i, n; |
|
308 |
bnser = ASN1_INTEGER_to_BN(serial, NULL); |
|
309 |
n = BN_bn2bin(bnser, hexbuf); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
310 |
for (i = 0; i < n; i++) { |
311 |
CatPrint(&serial_string, L"%02x:", hexbuf[i]); |
|
41.2.14
by Gary Ching-Pang Lin
Improve the layout of the key info |
312 |
}
|
313 |
}
|
|
314 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
315 |
if (serial_string.str) |
316 |
fields++; |
|
317 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
318 |
X509Name = X509_get_issuer_name(X509Cert); |
319 |
if (X509Name) { |
|
41.2.146
by Gary Ching-Pang Lin
MokManager: fetch more info from X509 name |
320 |
issuer = get_x509_name(X509Name); |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
321 |
if (issuer) |
322 |
fields++; |
|
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
323 |
}
|
324 |
||
325 |
X509Name = X509_get_subject_name(X509Cert); |
|
326 |
if (X509Name) { |
|
41.2.146
by Gary Ching-Pang Lin
MokManager: fetch more info from X509 name |
327 |
subject = get_x509_name(X509Name); |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
328 |
if (subject) |
329 |
fields++; |
|
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
330 |
}
|
331 |
||
332 |
time = X509_get_notBefore(X509Cert); |
|
333 |
if (time) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
334 |
from = get_x509_time(time); |
335 |
if (from) |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
336 |
fields++; |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
337 |
}
|
338 |
||
339 |
time = X509_get_notAfter(X509Cert); |
|
340 |
if (time) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
341 |
until = get_x509_time(time); |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
342 |
if (until) |
343 |
fields++; |
|
344 |
}
|
|
345 |
||
346 |
for (i=0; i<10; i++) |
|
347 |
CatPrint(&hash_string1, L"%02x ", hash[i]); |
|
348 |
for (i=10; i<20; i++) |
|
349 |
CatPrint(&hash_string2, L"%02x ", hash[i]); |
|
350 |
||
351 |
if (hash_string1.str) |
|
352 |
fields++; |
|
353 |
||
354 |
if (hash_string2.str) |
|
355 |
fields++; |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
356 |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
357 |
if (!fields) |
358 |
return; |
|
359 |
||
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
360 |
i = 0; |
361 |
text = AllocateZeroPool(sizeof(CHAR16 *) * (fields*3 + 1)); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
362 |
if (serial_string.str) { |
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
363 |
text[i++] = StrDuplicate(L"[Serial Number]"); |
364 |
text[i++] = serial_string.str; |
|
365 |
text[i++] = StrDuplicate(L""); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
366 |
}
|
367 |
if (issuer) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
368 |
text[i++] = StrDuplicate(L"[Issuer]"); |
369 |
text[i++] = issuer; |
|
370 |
text[i++] = StrDuplicate(L""); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
371 |
}
|
372 |
if (subject) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
373 |
text[i++] = StrDuplicate(L"[Subject]"); |
374 |
text[i++] = subject; |
|
375 |
text[i++] = StrDuplicate(L""); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
376 |
}
|
377 |
if (from) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
378 |
text[i++] = StrDuplicate(L"[Valid Not Before]"); |
379 |
text[i++] = from; |
|
380 |
text[i++] = StrDuplicate(L""); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
381 |
}
|
382 |
if (until) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
383 |
text[i++] = StrDuplicate(L"[Valid Not After]"); |
384 |
text[i++] = until; |
|
385 |
text[i++] = StrDuplicate(L""); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
386 |
}
|
387 |
if (hash_string1.str) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
388 |
text[i++] = StrDuplicate(L"[Fingerprint]"); |
389 |
text[i++] = hash_string1.str; |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
390 |
}
|
391 |
if (hash_string2.str) { |
|
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
392 |
text[i++] = hash_string2.str; |
393 |
text[i++] = StrDuplicate(L""); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
394 |
}
|
395 |
text[i] = NULL; |
|
396 |
||
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
397 |
console_print_box(text, -1); |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
398 |
|
399 |
for (i=0; text[i] != NULL; i++) |
|
400 |
FreePool(text[i]); |
|
401 |
||
402 |
FreePool(text); |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
403 |
}
|
404 |
||
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
405 |
static void show_efi_hash (UINT8 *hash) |
406 |
{
|
|
407 |
CHAR16 *text[5]; |
|
408 |
POOL_PRINT hash_string1; |
|
409 |
POOL_PRINT hash_string2; |
|
410 |
int i; |
|
411 |
||
412 |
ZeroMem(&hash_string1, sizeof(hash_string1)); |
|
413 |
ZeroMem(&hash_string2, sizeof(hash_string2)); |
|
414 |
||
415 |
text[0] = L"SHA256 hash"; |
|
416 |
text[1] = L""; |
|
417 |
||
418 |
for (i=0; i<16; i++) |
|
419 |
CatPrint(&hash_string1, L"%02x ", hash[i]); |
|
420 |
for (i=16; i<32; i++) |
|
421 |
CatPrint(&hash_string2, L"%02x ", hash[i]); |
|
422 |
||
423 |
text[2] = hash_string1.str; |
|
424 |
text[3] = hash_string2.str; |
|
425 |
text[4] = NULL; |
|
426 |
||
427 |
console_print_box(text, -1); |
|
428 |
||
429 |
if (hash_string1.str) |
|
430 |
FreePool(hash_string1.str); |
|
431 |
||
432 |
if (hash_string2.str) |
|
433 |
FreePool(hash_string2.str); |
|
434 |
}
|
|
435 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
436 |
static void show_mok_info (void *Mok, UINTN MokSize) |
437 |
{
|
|
438 |
EFI_STATUS efi_status; |
|
41.2.29
by Gary Ching-Pang Lin
Calculate SHA1 fingerprint |
439 |
UINT8 hash[SHA1_DIGEST_SIZE]; |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
440 |
X509 *X509Cert; |
441 |
||
442 |
if (!Mok || MokSize == 0) |
|
443 |
return; |
|
444 |
||
41.2.70
by Gary Ching-Pang Lin
MOK doesn't include the signature owner |
445 |
if (MokSize != SHA256_DIGEST_SIZE) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
446 |
efi_status = get_sha1sum(Mok, MokSize, hash); |
447 |
||
448 |
if (efi_status != EFI_SUCCESS) { |
|
449 |
console_notify(L"Failed to compute MOK fingerprint"); |
|
450 |
return; |
|
451 |
}
|
|
452 |
||
41.3.7
by Matthew Garrett
Don't print SHA1 sum when calculating file fingerprints |
453 |
if (X509ConstructCertificate(Mok, MokSize, |
454 |
(UINT8 **) &X509Cert) && X509Cert != NULL) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
455 |
show_x509_info(X509Cert, hash); |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
456 |
X509_free(X509Cert); |
457 |
} else { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
458 |
console_notify(L"Not a valid X509 certificate"); |
459 |
return; |
|
41.3.7
by Matthew Garrett
Don't print SHA1 sum when calculating file fingerprints |
460 |
}
|
41.2.14
by Gary Ching-Pang Lin
Improve the layout of the key info |
461 |
} else { |
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
462 |
show_efi_hash(Mok); |
41.2.14
by Gary Ching-Pang Lin
Improve the layout of the key info |
463 |
}
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
464 |
}
|
465 |
||
466 |
static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title) |
|
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
467 |
{
|
41.2.253
by Peter Jones
Make list_keys() index variables all be signed. |
468 |
INTN MokNum = 0; |
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
469 |
MokListNode *keys = NULL; |
41.2.16
by Gary Ching-Pang Lin
Make the key list interactive |
470 |
INTN key_num = 0; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
471 |
CHAR16 **menu_strings; |
41.2.253
by Peter Jones
Make list_keys() index variables all be signed. |
472 |
int i; |
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
473 |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
474 |
if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) + |
475 |
sizeof(EFI_SIGNATURE_DATA))) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
476 |
console_notify(L"No MOK keys found"); |
41.2.18
by Gary Ching-Pang Lin
Allow the new keys to be listed again |
477 |
return 0; |
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
478 |
}
|
479 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
480 |
MokNum = count_keys(KeyList, KeyListSize); |
41.2.262
by Sebastian Krahmer
OOB access when parsing MOK List/Certificates on MOK enrollment |
481 |
if (MokNum == 0) |
482 |
return 0; |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
483 |
keys = build_mok_list(MokNum, KeyList, KeyListSize); |
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
484 |
|
485 |
if (!keys) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
486 |
console_notify(L"Failed to construct key list"); |
41.2.18
by Gary Ching-Pang Lin
Allow the new keys to be listed again |
487 |
return 0; |
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
488 |
}
|
489 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
490 |
menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (MokNum + 2)); |
491 |
||
492 |
if (!menu_strings) |
|
493 |
return EFI_OUT_OF_RESOURCES; |
|
494 |
||
495 |
for (i=0; i<MokNum; i++) { |
|
496 |
menu_strings[i] = PoolPrint(L"View key %d", i); |
|
497 |
}
|
|
498 |
menu_strings[i] = StrDuplicate(L"Continue"); |
|
499 |
||
500 |
menu_strings[i+1] = NULL; |
|
501 |
||
502 |
while (key_num < MokNum) { |
|
503 |
key_num = console_select((CHAR16 *[]){ title, NULL }, |
|
504 |
menu_strings, 0); |
|
505 |
||
41.2.143
by Gary Ching-Pang Lin
MokManager: rearrange the output of MOK info |
506 |
if (key_num < 0) |
507 |
break; |
|
508 |
else if (key_num < MokNum) |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
509 |
show_mok_info(keys[key_num].Mok, keys[key_num].MokSize); |
510 |
}
|
|
511 |
||
512 |
for (i=0; menu_strings[i] != NULL; i++) |
|
513 |
FreePool(menu_strings[i]); |
|
514 |
||
515 |
FreePool(menu_strings); |
|
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
516 |
|
41.2.18
by Gary Ching-Pang Lin
Allow the new keys to be listed again |
517 |
FreePool(keys); |
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
518 |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
519 |
return EFI_SUCCESS; |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
520 |
}
|
521 |
||
41.2.224
by Gary Ching-Pang Lin
MokManager: handle the error status from ReadKeyStroke |
522 |
static EFI_STATUS get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show) |
41.2.32
by Gary Ching-Pang Lin
Use the same function to get commands and password |
523 |
{
|
524 |
EFI_INPUT_KEY key; |
|
41.2.224
by Gary Ching-Pang Lin
MokManager: handle the error status from ReadKeyStroke |
525 |
EFI_STATUS status; |
41.2.214
by Kees Cook
additional bounds-checking on section sizes |
526 |
unsigned int count = 0; |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
527 |
|
528 |
do { |
|
41.2.224
by Gary Ching-Pang Lin
MokManager: handle the error status from ReadKeyStroke |
529 |
status = console_get_keystroke(&key); |
530 |
if (EFI_ERROR (status)) { |
|
531 |
console_error(L"Failed to read the keystroke", status); |
|
532 |
*length = 0; |
|
533 |
return status; |
|
534 |
}
|
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
535 |
|
41.2.32
by Gary Ching-Pang Lin
Use the same function to get commands and password |
536 |
if ((count >= line_max && |
41.2.22
by Gary Ching-Pang Lin
Define the max length of password |
537 |
key.UnicodeChar != CHAR_BACKSPACE) || |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
538 |
key.UnicodeChar == CHAR_NULL || |
539 |
key.UnicodeChar == CHAR_TAB || |
|
41.2.25
by Gary Ching-Pang Lin
Filter out newline from the password array |
540 |
key.UnicodeChar == CHAR_LINEFEED || |
541 |
key.UnicodeChar == CHAR_CARRIAGE_RETURN) { |
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
542 |
continue; |
543 |
}
|
|
544 |
||
545 |
if (count == 0 && key.UnicodeChar == CHAR_BACKSPACE) { |
|
546 |
continue; |
|
547 |
} else if (key.UnicodeChar == CHAR_BACKSPACE) { |
|
41.2.32
by Gary Ching-Pang Lin
Use the same function to get commands and password |
548 |
if (show) { |
549 |
Print(L"\b"); |
|
550 |
}
|
|
551 |
line[--count] = '\0'; |
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
552 |
continue; |
553 |
}
|
|
554 |
||
41.2.32
by Gary Ching-Pang Lin
Use the same function to get commands and password |
555 |
if (show) { |
556 |
Print(L"%c", key.UnicodeChar); |
|
557 |
}
|
|
558 |
||
559 |
line[count++] = key.UnicodeChar; |
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
560 |
} while (key.UnicodeChar != CHAR_CARRIAGE_RETURN); |
561 |
Print(L"\n"); |
|
562 |
||
563 |
*length = count; |
|
564 |
||
41.2.224
by Gary Ching-Pang Lin
MokManager: handle the error status from ReadKeyStroke |
565 |
return EFI_SUCCESS; |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
566 |
}
|
567 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
568 |
static EFI_STATUS compute_pw_hash (void *Data, UINTN DataSize, UINT8 *password, |
569 |
UINT32 pw_length, UINT8 *hash) |
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
570 |
{
|
571 |
EFI_STATUS status; |
|
572 |
unsigned int ctxsize; |
|
573 |
void *ctx = NULL; |
|
574 |
||
575 |
ctxsize = Sha256GetContextSize(); |
|
576 |
ctx = AllocatePool(ctxsize); |
|
577 |
||
578 |
if (!ctx) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
579 |
console_notify(L"Unable to allocate memory for hash context"); |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
580 |
return EFI_OUT_OF_RESOURCES; |
581 |
}
|
|
582 |
||
583 |
if (!Sha256Init(ctx)) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
584 |
console_notify(L"Unable to initialise hash"); |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
585 |
status = EFI_OUT_OF_RESOURCES; |
586 |
goto done; |
|
587 |
}
|
|
588 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
589 |
if (Data && DataSize) { |
590 |
if (!(Sha256Update(ctx, Data, DataSize))) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
591 |
console_notify(L"Unable to generate hash"); |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
592 |
status = EFI_OUT_OF_RESOURCES; |
593 |
goto done; |
|
594 |
}
|
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
595 |
}
|
596 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
597 |
if (!(Sha256Update(ctx, password, pw_length))) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
598 |
console_notify(L"Unable to generate hash"); |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
599 |
status = EFI_OUT_OF_RESOURCES; |
600 |
goto done; |
|
601 |
}
|
|
602 |
||
603 |
if (!(Sha256Final(ctx, hash))) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
604 |
console_notify(L"Unable to finalise hash"); |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
605 |
status = EFI_OUT_OF_RESOURCES; |
606 |
goto done; |
|
607 |
}
|
|
608 |
||
609 |
status = EFI_SUCCESS; |
|
610 |
done: |
|
611 |
return status; |
|
612 |
}
|
|
613 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
614 |
static void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode) |
615 |
{
|
|
616 |
if (!SavedMode) { |
|
617 |
Print(L"Invalid parameter: SavedMode\n"); |
|
618 |
return; |
|
619 |
}
|
|
620 |
||
621 |
CopyMem(SavedMode, ST->ConOut->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE)); |
|
622 |
uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE); |
|
623 |
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, |
|
624 |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE); |
|
625 |
}
|
|
626 |
||
627 |
static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode) |
|
628 |
{
|
|
629 |
uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, |
|
630 |
SavedMode->CursorVisible); |
|
631 |
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, |
|
632 |
SavedMode->CursorColumn, SavedMode->CursorRow); |
|
633 |
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, |
|
634 |
SavedMode->Attribute); |
|
635 |
}
|
|
636 |
||
637 |
static UINT32 get_password (CHAR16 *prompt, CHAR16 *password, UINT32 max) |
|
638 |
{
|
|
639 |
SIMPLE_TEXT_OUTPUT_MODE SavedMode; |
|
640 |
CHAR16 *str; |
|
641 |
CHAR16 *message[2]; |
|
642 |
UINTN length; |
|
643 |
UINT32 pw_length; |
|
644 |
||
645 |
if (!prompt) |
|
646 |
prompt = L"Password:"; |
|
647 |
||
648 |
console_save_and_set_mode(&SavedMode); |
|
649 |
||
650 |
str = PoolPrint(L"%s ", prompt); |
|
651 |
if (!str) { |
|
652 |
console_errorbox(L"Failed to allocate prompt"); |
|
653 |
return 0; |
|
654 |
}
|
|
655 |
||
656 |
message[0] = str; |
|
657 |
message[1] = NULL; |
|
658 |
length = StrLen(message[0]); |
|
659 |
console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1); |
|
660 |
get_line(&pw_length, password, max, 0); |
|
661 |
||
662 |
console_restore_mode(&SavedMode); |
|
663 |
||
664 |
FreePool(str); |
|
665 |
||
666 |
return pw_length; |
|
667 |
}
|
|
668 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
669 |
static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt, |
670 |
void *Data, UINTN DataSize, |
|
671 |
UINT8 *auth, CHAR16 *prompt) |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
672 |
{
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
673 |
EFI_STATUS status; |
41.2.128
by Gary Ching-Pang Lin
MokManager: support SHA512-based crypt() hash |
674 |
UINT8 hash[128]; |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
675 |
UINT8 *auth_hash; |
676 |
UINT32 auth_size; |
|
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
677 |
CHAR16 password[PASSWORD_MAX]; |
678 |
UINT32 pw_length; |
|
679 |
UINT8 fail_count = 0; |
|
41.2.214
by Kees Cook
additional bounds-checking on section sizes |
680 |
unsigned int i; |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
681 |
|
682 |
if (pw_crypt) { |
|
41.2.128
by Gary Ching-Pang Lin
MokManager: support SHA512-based crypt() hash |
683 |
auth_hash = pw_crypt->hash; |
684 |
auth_size = get_hash_size (pw_crypt->method); |
|
685 |
if (auth_size == 0) |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
686 |
return EFI_INVALID_PARAMETER; |
687 |
} else if (auth) { |
|
688 |
auth_hash = auth; |
|
689 |
auth_size = SHA256_DIGEST_SIZE; |
|
690 |
} else { |
|
691 |
return EFI_INVALID_PARAMETER; |
|
692 |
}
|
|
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
693 |
|
694 |
while (fail_count < 3) { |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
695 |
pw_length = get_password(prompt, password, PASSWORD_MAX); |
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
696 |
|
697 |
if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) { |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
698 |
console_errorbox(L"Invalid password length"); |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
699 |
fail_count++; |
700 |
continue; |
|
701 |
}
|
|
702 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
703 |
/*
|
704 |
* Compute password hash
|
|
705 |
*/
|
|
706 |
if (pw_crypt) { |
|
707 |
char pw_ascii[PASSWORD_MAX + 1]; |
|
708 |
for (i = 0; i < pw_length; i++) |
|
709 |
pw_ascii[i] = (char)password[i]; |
|
710 |
pw_ascii[pw_length] = '\0'; |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
711 |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
712 |
status = password_crypt(pw_ascii, pw_length, pw_crypt, hash); |
713 |
} else { |
|
714 |
/*
|
|
715 |
* For backward compatibility
|
|
716 |
*/
|
|
717 |
status = compute_pw_hash(Data, DataSize, (UINT8 *)password, |
|
718 |
pw_length * sizeof(CHAR16), hash); |
|
719 |
}
|
|
720 |
if (status != EFI_SUCCESS) { |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
721 |
console_errorbox(L"Unable to generate password hash"); |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
722 |
fail_count++; |
723 |
continue; |
|
724 |
}
|
|
725 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
726 |
if (CompareMem(auth_hash, hash, auth_size) != 0) { |
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
727 |
console_errorbox(L"Password doesn't match"); |
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
728 |
fail_count++; |
729 |
continue; |
|
730 |
}
|
|
731 |
||
732 |
break; |
|
733 |
}
|
|
734 |
||
735 |
if (fail_count >= 3) |
|
736 |
return EFI_ACCESS_DENIED; |
|
737 |
||
738 |
return EFI_SUCCESS; |
|
739 |
}
|
|
740 |
||
41.2.42
by Matthew Garrett
Add an auth argument to store_keys() |
741 |
static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate) |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
742 |
{
|
743 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
744 |
EFI_STATUS efi_status; |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
745 |
UINT8 auth[PASSWORD_CRYPT_SIZE]; |
746 |
UINTN auth_size = PASSWORD_CRYPT_SIZE; |
|
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
747 |
UINT32 attributes; |
748 |
||
41.2.42
by Matthew Garrett
Add an auth argument to store_keys() |
749 |
if (authenticate) { |
750 |
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth", |
|
751 |
&shim_lock_guid, |
|
752 |
&attributes, &auth_size, auth); |
|
753 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
754 |
if (efi_status != EFI_SUCCESS || |
755 |
(auth_size != SHA256_DIGEST_SIZE && |
|
756 |
auth_size != PASSWORD_CRYPT_SIZE)) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
757 |
console_error(L"Failed to get MokAuth", efi_status); |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
758 |
return efi_status; |
759 |
}
|
|
760 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
761 |
if (auth_size == PASSWORD_CRYPT_SIZE) { |
762 |
efi_status = match_password((PASSWORD_CRYPT *)auth, |
|
763 |
NULL, 0, NULL, NULL); |
|
764 |
} else { |
|
765 |
efi_status = match_password(NULL, MokNew, MokNewSize, |
|
766 |
auth, NULL); |
|
767 |
}
|
|
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
768 |
if (efi_status != EFI_SUCCESS) |
41.2.42
by Matthew Garrett
Add an auth argument to store_keys() |
769 |
return EFI_ACCESS_DENIED; |
41.2.21
by Gary Ching-Pang Lin
Request a password to verify the key list |
770 |
}
|
771 |
||
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
772 |
if (!MokNewSize) { |
773 |
/* Delete MOK */
|
|
774 |
efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList", |
|
775 |
&shim_lock_guid, |
|
776 |
EFI_VARIABLE_NON_VOLATILE
|
|
41.3.11
by Matthew Garrett
Delete MokList properly |
777 |
| EFI_VARIABLE_BOOTSERVICE_ACCESS, |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
778 |
0, NULL); |
779 |
} else { |
|
780 |
/* Write new MOK */
|
|
781 |
efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList", |
|
782 |
&shim_lock_guid, |
|
783 |
EFI_VARIABLE_NON_VOLATILE
|
|
784 |
| EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
785 |
| EFI_VARIABLE_APPEND_WRITE, |
|
786 |
MokNewSize, MokNew); |
|
787 |
}
|
|
788 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
789 |
if (efi_status != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
790 |
console_error(L"Failed to set variable", efi_status); |
41.2.20
by Gary Ching-Pang Lin
Erase stored keys when there is no key in the new key list |
791 |
return efi_status; |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
792 |
}
|
793 |
||
41.2.20
by Gary Ching-Pang Lin
Erase stored keys when there is no key in the new key list |
794 |
return EFI_SUCCESS; |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
795 |
}
|
796 |
||
41.2.42
by Matthew Garrett
Add an auth argument to store_keys() |
797 |
static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { |
41.2.68
by Gary Ching-Pang Lin
Reboot the system after enrolling/erasing keys |
798 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
799 |
EFI_STATUS efi_status; |
800 |
||
801 |
if (list_keys(MokNew, MokNewSize, L"[Enroll MOK]") != EFI_SUCCESS) |
|
802 |
return 0; |
|
803 |
||
804 |
if (console_yes_no((CHAR16 *[]){L"Enroll the key(s)?", NULL}) == 0) |
|
805 |
return 0; |
|
806 |
||
807 |
efi_status = store_keys(MokNew, MokNewSize, auth); |
|
808 |
||
809 |
if (efi_status != EFI_SUCCESS) { |
|
810 |
console_notify(L"Failed to enroll keys\n"); |
|
811 |
return -1; |
|
812 |
}
|
|
813 |
||
814 |
if (auth) { |
|
41.2.68
by Gary Ching-Pang Lin
Reboot the system after enrolling/erasing keys |
815 |
LibDeleteVariable(L"MokNew", &shim_lock_guid); |
816 |
LibDeleteVariable(L"MokAuth", &shim_lock_guid); |
|
817 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
818 |
console_notify(L"The system must now be rebooted"); |
41.2.68
by Gary Ching-Pang Lin
Reboot the system after enrolling/erasing keys |
819 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, |
820 |
EFI_SUCCESS, 0, NULL); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
821 |
console_notify(L"Failed to reboot"); |
41.2.68
by Gary Ching-Pang Lin
Reboot the system after enrolling/erasing keys |
822 |
return -1; |
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
823 |
}
|
824 |
||
825 |
return 0; |
|
826 |
}
|
|
827 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
828 |
static INTN mok_reset_prompt () |
829 |
{
|
|
830 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
831 |
EFI_STATUS efi_status; |
|
832 |
||
833 |
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); |
|
834 |
||
835 |
if (console_yes_no((CHAR16 *[]){L"Erase all stored keys?", NULL }) == 0) |
|
836 |
return 0; |
|
837 |
||
838 |
efi_status = store_keys(NULL, 0, TRUE); |
|
839 |
||
840 |
if (efi_status != EFI_SUCCESS) { |
|
841 |
console_notify(L"Failed to erase keys\n"); |
|
842 |
return -1; |
|
843 |
}
|
|
844 |
||
845 |
LibDeleteVariable(L"MokNew", &shim_lock_guid); |
|
846 |
LibDeleteVariable(L"MokAuth", &shim_lock_guid); |
|
847 |
||
848 |
console_notify(L"The system must now be rebooted"); |
|
849 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, |
|
850 |
EFI_SUCCESS, 0, NULL); |
|
851 |
console_notify(L"Failed to reboot\n"); |
|
852 |
return -1; |
|
853 |
}
|
|
854 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
855 |
static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num) |
856 |
{
|
|
857 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
858 |
EFI_STATUS efi_status; |
|
859 |
EFI_SIGNATURE_LIST *CertList; |
|
860 |
EFI_SIGNATURE_DATA *CertData; |
|
861 |
void *Data = NULL, *ptr; |
|
862 |
INTN DataSize = 0; |
|
863 |
int i; |
|
864 |
||
865 |
for (i = 0; i < key_num; i++) { |
|
866 |
if (list[i].Mok == NULL) |
|
867 |
continue; |
|
868 |
||
869 |
DataSize += sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID); |
|
870 |
DataSize += list[i].MokSize; |
|
871 |
}
|
|
872 |
||
873 |
Data = AllocatePool(DataSize); |
|
874 |
if (Data == NULL && DataSize != 0) |
|
875 |
return EFI_OUT_OF_RESOURCES; |
|
876 |
||
877 |
ptr = Data; |
|
878 |
||
879 |
for (i = 0; i < key_num; i++) { |
|
880 |
if (list[i].Mok == NULL) |
|
881 |
continue; |
|
882 |
||
883 |
CertList = (EFI_SIGNATURE_LIST *)ptr; |
|
884 |
CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) + |
|
885 |
sizeof(EFI_SIGNATURE_LIST)); |
|
886 |
||
887 |
CertList->SignatureType = list[i].Type; |
|
888 |
CertList->SignatureListSize = list[i].MokSize + |
|
889 |
sizeof(EFI_SIGNATURE_LIST) + |
|
890 |
sizeof(EFI_SIGNATURE_DATA) - 1; |
|
891 |
CertList->SignatureHeaderSize = 0; |
|
892 |
CertList->SignatureSize = list[i].MokSize + sizeof(EFI_GUID); |
|
893 |
||
894 |
CertData->SignatureOwner = shim_lock_guid; |
|
895 |
CopyMem(CertData->SignatureData, list[i].Mok, list[i].MokSize); |
|
896 |
||
897 |
ptr = (uint8_t *)ptr + sizeof(EFI_SIGNATURE_LIST) + |
|
898 |
sizeof(EFI_GUID) + list[i].MokSize; |
|
899 |
}
|
|
900 |
||
901 |
efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList", |
|
902 |
&shim_lock_guid, |
|
903 |
EFI_VARIABLE_NON_VOLATILE
|
|
904 |
| EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
905 |
DataSize, Data); |
|
906 |
if (Data) |
|
907 |
FreePool(Data); |
|
908 |
||
909 |
if (efi_status != EFI_SUCCESS) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
910 |
console_error(L"Failed to set variable", efi_status); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
911 |
return efi_status; |
912 |
}
|
|
913 |
||
914 |
return EFI_SUCCESS; |
|
915 |
}
|
|
916 |
||
917 |
static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize) |
|
918 |
{
|
|
919 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
920 |
EFI_STATUS efi_status; |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
921 |
UINT8 auth[PASSWORD_CRYPT_SIZE]; |
922 |
UINTN auth_size = PASSWORD_CRYPT_SIZE; |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
923 |
UINT32 attributes; |
41.2.153
by Gary Ching-Pang Lin
Merge variable retrieving functions |
924 |
UINT8 *MokListData = NULL; |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
925 |
UINTN MokListDataSize = 0; |
926 |
MokListNode *mok, *del_key; |
|
927 |
INTN mok_num, del_num; |
|
928 |
int i, j; |
|
929 |
||
930 |
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth", |
|
931 |
&shim_lock_guid, |
|
932 |
&attributes, &auth_size, auth); |
|
933 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
934 |
if (efi_status != EFI_SUCCESS || |
935 |
(auth_size != SHA256_DIGEST_SIZE && auth_size != PASSWORD_CRYPT_SIZE)) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
936 |
console_error(L"Failed to get MokDelAuth", efi_status); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
937 |
return efi_status; |
938 |
}
|
|
939 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
940 |
if (auth_size == PASSWORD_CRYPT_SIZE) { |
941 |
efi_status = match_password((PASSWORD_CRYPT *)auth, NULL, 0, |
|
942 |
NULL, NULL); |
|
943 |
} else { |
|
944 |
efi_status = match_password(NULL, MokDel, MokDelSize, auth, NULL); |
|
945 |
}
|
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
946 |
if (efi_status != EFI_SUCCESS) |
947 |
return EFI_ACCESS_DENIED; |
|
948 |
||
41.2.153
by Gary Ching-Pang Lin
Merge variable retrieving functions |
949 |
efi_status = get_variable_attr (L"MokList", &MokListData, &MokListDataSize, |
950 |
shim_lock_guid, &attributes); |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
951 |
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
952 |
console_alertbox((CHAR16 *[]){L"MokList is compromised!", |
953 |
L"Erase all keys in MokList!", |
|
954 |
NULL}); |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
955 |
if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
956 |
console_notify(L"Failed to erase MokList"); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
957 |
}
|
958 |
return EFI_ACCESS_DENIED; |
|
959 |
}
|
|
960 |
||
961 |
/* Nothing to do */
|
|
962 |
if (!MokListData || MokListDataSize == 0) |
|
963 |
return EFI_SUCCESS; |
|
964 |
||
965 |
/* Construct lists */
|
|
966 |
mok_num = count_keys(MokListData, MokListDataSize); |
|
967 |
mok = build_mok_list(mok_num, MokListData, MokListDataSize); |
|
968 |
del_num = count_keys(MokDel, MokDelSize); |
|
969 |
del_key = build_mok_list(del_num, MokDel, MokDelSize); |
|
970 |
||
971 |
/* Search and destroy */
|
|
972 |
for (i = 0; i < del_num; i++) { |
|
973 |
UINT32 key_size = del_key[i].MokSize; |
|
974 |
void *key = del_key[i].Mok; |
|
975 |
for (j = 0; j < mok_num; j++) { |
|
976 |
if (mok[j].MokSize == key_size && |
|
977 |
CompareMem(key, mok[j].Mok, key_size) == 0) { |
|
978 |
/* Remove the key */
|
|
979 |
mok[j].Mok = NULL; |
|
980 |
mok[j].MokSize = 0; |
|
981 |
}
|
|
982 |
}
|
|
983 |
}
|
|
984 |
||
985 |
efi_status = write_back_mok_list(mok, mok_num); |
|
986 |
||
987 |
if (MokListData) |
|
988 |
FreePool(MokListData); |
|
989 |
if (mok) |
|
990 |
FreePool(mok); |
|
991 |
if (del_key) |
|
992 |
FreePool(del_key); |
|
993 |
||
994 |
return efi_status; |
|
995 |
}
|
|
996 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
997 |
static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize) |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
998 |
{
|
999 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
1000 |
EFI_STATUS efi_status; |
|
1001 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1002 |
if (list_keys(MokDel, MokDelSize, L"[Delete MOK]") != EFI_SUCCESS) { |
1003 |
return 0; |
|
1004 |
}
|
|
1005 |
||
1006 |
if (console_yes_no((CHAR16 *[]){L"Delete the key(s)?", NULL}) == 0) |
|
1007 |
return 0; |
|
1008 |
||
1009 |
efi_status = delete_keys(MokDel, MokDelSize); |
|
1010 |
||
1011 |
if (efi_status != EFI_SUCCESS) { |
|
1012 |
console_notify(L"Failed to delete keys"); |
|
1013 |
return -1; |
|
1014 |
}
|
|
1015 |
||
1016 |
LibDeleteVariable(L"MokDel", &shim_lock_guid); |
|
1017 |
LibDeleteVariable(L"MokDelAuth", &shim_lock_guid); |
|
1018 |
||
1019 |
console_notify(L"The system must now be rebooted"); |
|
1020 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, |
|
1021 |
EFI_SUCCESS, 0, NULL); |
|
1022 |
console_notify(L"Failed to reboot"); |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1023 |
return -1; |
1024 |
}
|
|
1025 |
||
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1026 |
static CHAR16 get_password_charater (CHAR16 *prompt) |
1027 |
{
|
|
1028 |
SIMPLE_TEXT_OUTPUT_MODE SavedMode; |
|
41.2.224
by Gary Ching-Pang Lin
MokManager: handle the error status from ReadKeyStroke |
1029 |
EFI_STATUS status; |
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1030 |
CHAR16 *message[2]; |
1031 |
CHAR16 character; |
|
1032 |
UINTN length; |
|
1033 |
UINT32 pw_length; |
|
1034 |
||
1035 |
if (!prompt) |
|
1036 |
prompt = L"Password charater: "; |
|
1037 |
||
1038 |
console_save_and_set_mode(&SavedMode); |
|
1039 |
||
1040 |
message[0] = prompt; |
|
1041 |
message[1] = NULL; |
|
1042 |
length = StrLen(message[0]); |
|
1043 |
console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1); |
|
41.2.224
by Gary Ching-Pang Lin
MokManager: handle the error status from ReadKeyStroke |
1044 |
status = get_line(&pw_length, &character, 1, 0); |
1045 |
if (EFI_ERROR(status)) |
|
1046 |
character = 0; |
|
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1047 |
|
1048 |
console_restore_mode(&SavedMode); |
|
1049 |
||
1050 |
return character; |
|
1051 |
}
|
|
1052 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1053 |
static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) { |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1054 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
1055 |
EFI_STATUS efi_status; |
|
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1056 |
SIMPLE_TEXT_OUTPUT_MODE SavedMode; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1057 |
MokSBvar *var = MokSB; |
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1058 |
CHAR16 *message[4]; |
41.3.18
by Matthew Garrett
Improve signature validation enable/disable |
1059 |
CHAR16 pass1, pass2, pass3; |
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1060 |
CHAR16 *str; |
41.3.18
by Matthew Garrett
Improve signature validation enable/disable |
1061 |
UINT8 fail_count = 0; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1062 |
UINT8 sbval = 1; |
41.3.18
by Matthew Garrett
Improve signature validation enable/disable |
1063 |
UINT8 pos1, pos2, pos3; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1064 |
int ret; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1065 |
|
1066 |
if (MokSBSize != sizeof(MokSBvar)) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1067 |
console_notify(L"Invalid MokSB variable contents"); |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1068 |
return -1; |
1069 |
}
|
|
1070 |
||
41.3.8
by Matthew Garrett
Clear screen before prompting |
1071 |
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); |
1072 |
||
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1073 |
message[0] = L"Change Secure Boot state"; |
1074 |
message[1] = NULL; |
|
1075 |
||
1076 |
console_save_and_set_mode(&SavedMode); |
|
1077 |
console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1); |
|
1078 |
console_restore_mode(&SavedMode); |
|
1079 |
||
41.3.18
by Matthew Garrett
Improve signature validation enable/disable |
1080 |
while (fail_count < 3) { |
1081 |
RandomBytes (&pos1, sizeof(pos1)); |
|
1082 |
pos1 = (pos1 % var->PWLen); |
|
1083 |
||
1084 |
do { |
|
1085 |
RandomBytes (&pos2, sizeof(pos2)); |
|
1086 |
pos2 = (pos2 % var->PWLen); |
|
1087 |
} while (pos2 == pos1); |
|
1088 |
||
1089 |
do { |
|
1090 |
RandomBytes (&pos3, sizeof(pos3)); |
|
1091 |
pos3 = (pos3 % var->PWLen) ; |
|
1092 |
} while (pos3 == pos2 || pos3 == pos1); |
|
1093 |
||
41.2.144
by Gary Ching-Pang Lin
MokManager: enhance the password prompt for SB state |
1094 |
str = PoolPrint(L"Enter password character %d: ", pos1 + 1); |
1095 |
if (!str) { |
|
1096 |
console_errorbox(L"Failed to allocate buffer"); |
|
1097 |
return -1; |
|
1098 |
}
|
|
1099 |
pass1 = get_password_charater(str); |
|
1100 |
FreePool(str); |
|
1101 |
||
1102 |
str = PoolPrint(L"Enter password character %d: ", pos2 + 1); |
|
1103 |
if (!str) { |
|
1104 |
console_errorbox(L"Failed to allocate buffer"); |
|
1105 |
return -1; |
|
1106 |
}
|
|
1107 |
pass2 = get_password_charater(str); |
|
1108 |
FreePool(str); |
|
1109 |
||
1110 |
str = PoolPrint(L"Enter password character %d: ", pos3 + 1); |
|
1111 |
if (!str) { |
|
1112 |
console_errorbox(L"Failed to allocate buffer"); |
|
1113 |
return -1; |
|
1114 |
}
|
|
1115 |
pass3 = get_password_charater(str); |
|
1116 |
FreePool(str); |
|
41.3.18
by Matthew Garrett
Improve signature validation enable/disable |
1117 |
|
1118 |
if (pass1 != var->Password[pos1] || |
|
1119 |
pass2 != var->Password[pos2] || |
|
1120 |
pass3 != var->Password[pos3]) { |
|
41.3.12
by Matthew Garrett
Update image validation enable/disable |
1121 |
Print(L"Invalid character\n"); |
1122 |
fail_count++; |
|
1123 |
} else { |
|
41.3.18
by Matthew Garrett
Improve signature validation enable/disable |
1124 |
break; |
41.3.12
by Matthew Garrett
Update image validation enable/disable |
1125 |
}
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1126 |
}
|
1127 |
||
1128 |
if (fail_count >= 3) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1129 |
console_notify(L"Password limit reached"); |
1130 |
return -1; |
|
1131 |
}
|
|
1132 |
||
1133 |
if (var->MokSBState == 0) |
|
1134 |
ret = console_yes_no((CHAR16 *[]){L"Disable Secure Boot", NULL}); |
|
1135 |
else
|
|
1136 |
ret = console_yes_no((CHAR16 *[]){L"Enable Secure Boot", NULL}); |
|
1137 |
||
1138 |
if (ret == 0) { |
|
1139 |
LibDeleteVariable(L"MokSB", &shim_lock_guid); |
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1140 |
return -1; |
1141 |
}
|
|
1142 |
||
1143 |
if (var->MokSBState == 0) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1144 |
efi_status = uefi_call_wrapper(RT->SetVariable, |
1145 |
5, L"MokSBState", |
|
1146 |
&shim_lock_guid, |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1147 |
EFI_VARIABLE_NON_VOLATILE | |
1148 |
EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1149 |
1, &sbval); |
1150 |
if (efi_status != EFI_SUCCESS) { |
|
1151 |
console_notify(L"Failed to set Secure Boot state"); |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1152 |
return -1; |
1153 |
}
|
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1154 |
} else { |
41.2.223
by Gary Ching-Pang Lin
MokManager: delete the BS+NV variables the right way |
1155 |
efi_status = uefi_call_wrapper(RT->SetVariable, |
1156 |
5, L"MokSBState", |
|
1157 |
&shim_lock_guid, |
|
1158 |
EFI_VARIABLE_NON_VOLATILE | |
|
1159 |
EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
1160 |
0, NULL); |
|
1161 |
if (efi_status != EFI_SUCCESS) { |
|
1162 |
console_notify(L"Failed to delete Secure Boot state"); |
|
1163 |
return -1; |
|
1164 |
}
|
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1165 |
}
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1166 |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1167 |
console_notify(L"The system must now be rebooted"); |
1168 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, |
|
1169 |
EFI_SUCCESS, 0, NULL); |
|
1170 |
console_notify(L"Failed to reboot"); |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1171 |
return -1; |
1172 |
}
|
|
1173 |
||
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1174 |
static INTN mok_db_prompt (void *MokDB, UINTN MokDBSize) { |
1175 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
1176 |
EFI_STATUS efi_status; |
|
1177 |
SIMPLE_TEXT_OUTPUT_MODE SavedMode; |
|
1178 |
MokDBvar *var = MokDB; |
|
1179 |
CHAR16 *message[4]; |
|
1180 |
CHAR16 pass1, pass2, pass3; |
|
1181 |
CHAR16 *str; |
|
1182 |
UINT8 fail_count = 0; |
|
1183 |
UINT8 dbval = 1; |
|
1184 |
UINT8 pos1, pos2, pos3; |
|
1185 |
int ret; |
|
1186 |
||
1187 |
if (MokDBSize != sizeof(MokDBvar)) { |
|
1188 |
console_notify(L"Invalid MokDB variable contents"); |
|
1189 |
return -1; |
|
1190 |
}
|
|
1191 |
||
1192 |
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); |
|
1193 |
||
1194 |
message[0] = L"Change DB state"; |
|
1195 |
message[1] = NULL; |
|
1196 |
||
1197 |
console_save_and_set_mode(&SavedMode); |
|
1198 |
console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1); |
|
1199 |
console_restore_mode(&SavedMode); |
|
1200 |
||
1201 |
while (fail_count < 3) { |
|
1202 |
RandomBytes (&pos1, sizeof(pos1)); |
|
1203 |
pos1 = (pos1 % var->PWLen); |
|
1204 |
||
1205 |
do { |
|
1206 |
RandomBytes (&pos2, sizeof(pos2)); |
|
1207 |
pos2 = (pos2 % var->PWLen); |
|
1208 |
} while (pos2 == pos1); |
|
1209 |
||
1210 |
do { |
|
1211 |
RandomBytes (&pos3, sizeof(pos3)); |
|
1212 |
pos3 = (pos3 % var->PWLen) ; |
|
1213 |
} while (pos3 == pos2 || pos3 == pos1); |
|
1214 |
||
1215 |
str = PoolPrint(L"Enter password character %d: ", pos1 + 1); |
|
1216 |
if (!str) { |
|
1217 |
console_errorbox(L"Failed to allocate buffer"); |
|
1218 |
return -1; |
|
1219 |
}
|
|
1220 |
pass1 = get_password_charater(str); |
|
1221 |
FreePool(str); |
|
1222 |
||
1223 |
str = PoolPrint(L"Enter password character %d: ", pos2 + 1); |
|
1224 |
if (!str) { |
|
1225 |
console_errorbox(L"Failed to allocate buffer"); |
|
1226 |
return -1; |
|
1227 |
}
|
|
1228 |
pass2 = get_password_charater(str); |
|
1229 |
FreePool(str); |
|
1230 |
||
1231 |
str = PoolPrint(L"Enter password character %d: ", pos3 + 1); |
|
1232 |
if (!str) { |
|
1233 |
console_errorbox(L"Failed to allocate buffer"); |
|
1234 |
return -1; |
|
1235 |
}
|
|
1236 |
pass3 = get_password_charater(str); |
|
1237 |
FreePool(str); |
|
1238 |
||
1239 |
if (pass1 != var->Password[pos1] || |
|
1240 |
pass2 != var->Password[pos2] || |
|
1241 |
pass3 != var->Password[pos3]) { |
|
1242 |
Print(L"Invalid character\n"); |
|
1243 |
fail_count++; |
|
1244 |
} else { |
|
1245 |
break; |
|
1246 |
}
|
|
1247 |
}
|
|
1248 |
||
1249 |
if (fail_count >= 3) { |
|
1250 |
console_notify(L"Password limit reached"); |
|
1251 |
return -1; |
|
1252 |
}
|
|
1253 |
||
1254 |
if (var->MokDBState == 0) |
|
1255 |
ret = console_yes_no((CHAR16 *[]){L"Ignore DB certs/hashes", NULL}); |
|
1256 |
else
|
|
1257 |
ret = console_yes_no((CHAR16 *[]){L"Use DB certs/hashes", NULL}); |
|
1258 |
||
1259 |
if (ret == 0) { |
|
1260 |
LibDeleteVariable(L"MokDB", &shim_lock_guid); |
|
1261 |
return -1; |
|
1262 |
}
|
|
1263 |
||
1264 |
if (var->MokDBState == 0) { |
|
1265 |
efi_status = uefi_call_wrapper(RT->SetVariable, |
|
1266 |
5, L"MokDBState", |
|
1267 |
&shim_lock_guid, |
|
1268 |
EFI_VARIABLE_NON_VOLATILE | |
|
1269 |
EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
1270 |
1, &dbval); |
|
1271 |
if (efi_status != EFI_SUCCESS) { |
|
1272 |
console_notify(L"Failed to set DB state"); |
|
1273 |
return -1; |
|
1274 |
}
|
|
1275 |
} else { |
|
41.2.223
by Gary Ching-Pang Lin
MokManager: delete the BS+NV variables the right way |
1276 |
efi_status = uefi_call_wrapper(RT->SetVariable, 5, |
1277 |
L"MokDBState", |
|
1278 |
&shim_lock_guid, |
|
1279 |
EFI_VARIABLE_NON_VOLATILE | |
|
1280 |
EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
1281 |
0, NULL); |
|
1282 |
if (efi_status != EFI_SUCCESS) { |
|
1283 |
console_notify(L"Failed to delete DB state"); |
|
1284 |
return -1; |
|
1285 |
}
|
|
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1286 |
}
|
1287 |
||
1288 |
console_notify(L"The system must now be rebooted"); |
|
1289 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, |
|
1290 |
EFI_SUCCESS, 0, NULL); |
|
1291 |
console_notify(L"Failed to reboot"); |
|
1292 |
return -1; |
|
1293 |
}
|
|
1294 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1295 |
static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) { |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1296 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
1297 |
EFI_STATUS efi_status; |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1298 |
UINT8 hash[PASSWORD_CRYPT_SIZE]; |
1299 |
UINT8 clear = 0; |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1300 |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1301 |
if (MokPWSize != SHA256_DIGEST_SIZE && MokPWSize != PASSWORD_CRYPT_SIZE) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1302 |
console_notify(L"Invalid MokPW variable contents"); |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1303 |
return -1; |
1304 |
}
|
|
1305 |
||
1306 |
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); |
|
1307 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1308 |
SetMem(hash, PASSWORD_CRYPT_SIZE, 0); |
1309 |
||
1310 |
if (MokPWSize == PASSWORD_CRYPT_SIZE) { |
|
1311 |
if (CompareMem(MokPW, hash, PASSWORD_CRYPT_SIZE) == 0) |
|
1312 |
clear = 1; |
|
1313 |
} else { |
|
1314 |
if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0) |
|
1315 |
clear = 1; |
|
1316 |
}
|
|
1317 |
||
1318 |
if (clear) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1319 |
if (console_yes_no((CHAR16 *[]){L"Clear MOK password?", NULL}) == 0) |
1320 |
return 0; |
|
1321 |
||
41.2.223
by Gary Ching-Pang Lin
MokManager: delete the BS+NV variables the right way |
1322 |
uefi_call_wrapper(RT->SetVariable, 5, L"MokPWStore", |
1323 |
&shim_lock_guid, |
|
1324 |
EFI_VARIABLE_NON_VOLATILE
|
|
1325 |
| EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
1326 |
0, NULL); |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1327 |
LibDeleteVariable(L"MokPW", &shim_lock_guid); |
41.2.145
by Gary Ching-Pang Lin
MokManager: reboot the system after clearing MOK password |
1328 |
console_notify(L"The system must now be rebooted"); |
1329 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0, |
|
1330 |
NULL); |
|
1331 |
console_notify(L"Failed to reboot"); |
|
1332 |
return -1; |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1333 |
}
|
1334 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1335 |
if (MokPWSize == PASSWORD_CRYPT_SIZE) { |
1336 |
efi_status = match_password((PASSWORD_CRYPT *)MokPW, NULL, 0, |
|
1337 |
NULL, L"Confirm MOK passphrase: "); |
|
1338 |
} else { |
|
1339 |
efi_status = match_password(NULL, NULL, 0, MokPW, |
|
1340 |
L"Confirm MOK passphrase: "); |
|
1341 |
}
|
|
1342 |
||
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1343 |
if (efi_status != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1344 |
console_notify(L"Password limit reached"); |
1345 |
return -1; |
|
1346 |
}
|
|
1347 |
||
1348 |
if (console_yes_no((CHAR16 *[]){L"Set MOK password?", NULL}) == 0) |
|
1349 |
return 0; |
|
1350 |
||
1351 |
efi_status = uefi_call_wrapper(RT->SetVariable, 5, |
|
1352 |
L"MokPWStore", |
|
1353 |
&shim_lock_guid, |
|
1354 |
EFI_VARIABLE_NON_VOLATILE | |
|
1355 |
EFI_VARIABLE_BOOTSERVICE_ACCESS, |
|
1356 |
MokPWSize, MokPW); |
|
1357 |
if (efi_status != EFI_SUCCESS) { |
|
1358 |
console_notify(L"Failed to set MOK password"); |
|
1359 |
return -1; |
|
1360 |
}
|
|
1361 |
||
1362 |
LibDeleteVariable(L"MokPW", &shim_lock_guid); |
|
1363 |
||
1364 |
console_notify(L"The system must now be rebooted"); |
|
1365 |
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0, |
|
1366 |
NULL); |
|
1367 |
console_notify(L"Failed to reboot"); |
|
1368 |
return -1; |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1369 |
}
|
1370 |
||
41.2.221
by Gary Ching-Pang Lin
Check the first 4 bytes of the certificate |
1371 |
static BOOLEAN verify_certificate(UINT8 *cert, UINTN size) |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1372 |
{
|
1373 |
X509 *X509Cert; |
|
41.2.221
by Gary Ching-Pang Lin
Check the first 4 bytes of the certificate |
1374 |
UINTN length; |
1375 |
if (!cert || size < 0) |
|
1376 |
return FALSE; |
|
1377 |
||
1378 |
/*
|
|
1379 |
* A DER encoding x509 certificate starts with SEQUENCE(0x30),
|
|
1380 |
* the number of length bytes, and the number of value bytes.
|
|
1381 |
* The size of a x509 certificate is usually between 127 bytes
|
|
1382 |
* and 64KB. For convenience, assume the number of value bytes
|
|
1383 |
* is 2, i.e. the second byte is 0x82.
|
|
1384 |
*/
|
|
1385 |
if (cert[0] != 0x30 || cert[1] != 0x82) { |
|
1386 |
console_notify(L"Not a DER encoding X509 certificate"); |
|
1387 |
return FALSE; |
|
1388 |
}
|
|
1389 |
||
1390 |
length = (cert[2]<<8 | cert[3]); |
|
1391 |
if (length != (size - 4)) { |
|
1392 |
console_notify(L"Invalid X509 certificate: Inconsistent size"); |
|
1393 |
return FALSE; |
|
1394 |
}
|
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1395 |
|
1396 |
if (!(X509ConstructCertificate(cert, size, (UINT8 **) &X509Cert)) || |
|
1397 |
X509Cert == NULL) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1398 |
console_notify(L"Invalid X509 certificate"); |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1399 |
return FALSE; |
1400 |
}
|
|
1401 |
||
1402 |
X509_free(X509Cert); |
|
1403 |
return TRUE; |
|
1404 |
}
|
|
1405 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1406 |
static EFI_STATUS enroll_file (void *data, UINTN datasize, BOOLEAN hash) |
1407 |
{
|
|
1408 |
EFI_STATUS status = EFI_SUCCESS; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1409 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
1410 |
EFI_SIGNATURE_LIST *CertList; |
|
1411 |
EFI_SIGNATURE_DATA *CertData; |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1412 |
UINTN mokbuffersize; |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1413 |
void *mokbuffer = NULL; |
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
1414 |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1415 |
if (hash) { |
1416 |
UINT8 sha256[SHA256_DIGEST_SIZE]; |
|
1417 |
UINT8 sha1[SHA1_DIGEST_SIZE]; |
|
1418 |
SHIM_LOCK *shim_lock; |
|
1419 |
EFI_GUID shim_guid = SHIM_LOCK_GUID; |
|
1420 |
PE_COFF_LOADER_IMAGE_CONTEXT context; |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1421 |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1422 |
status = LibLocateProtocol(&shim_guid, (VOID **)&shim_lock); |
1423 |
||
1424 |
if (status != EFI_SUCCESS) |
|
1425 |
goto out; |
|
1426 |
||
1427 |
mokbuffersize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) + |
|
1428 |
SHA256_DIGEST_SIZE; |
|
1429 |
||
1430 |
mokbuffer = AllocatePool(mokbuffersize); |
|
41.2.43
by Matthew Garrett
Fix filesystem enrollment |
1431 |
|
1432 |
if (!mokbuffer) |
|
1433 |
goto out; |
|
1434 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1435 |
status = shim_lock->Context(data, datasize, &context); |
1436 |
||
1437 |
if (status != EFI_SUCCESS) |
|
1438 |
goto out; |
|
1439 |
||
1440 |
status = shim_lock->Hash(data, datasize, &context, sha256, |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1441 |
sha1); |
1442 |
||
1443 |
if (status != EFI_SUCCESS) |
|
1444 |
goto out; |
|
1445 |
||
1446 |
CertList = mokbuffer; |
|
41.2.152
by Gary Ching-Pang Lin
Merge signature.h into efiauthenticated.h and guid.h |
1447 |
CertList->SignatureType = EFI_CERT_SHA256_GUID; |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1448 |
CertList->SignatureSize = 16 + SHA256_DIGEST_SIZE; |
1449 |
CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) + |
|
1450 |
sizeof(EFI_SIGNATURE_LIST)); |
|
1451 |
CopyMem(CertData->SignatureData, sha256, SHA256_DIGEST_SIZE); |
|
41.2.43
by Matthew Garrett
Fix filesystem enrollment |
1452 |
} else { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1453 |
mokbuffersize = datasize + sizeof(EFI_SIGNATURE_LIST) + |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1454 |
sizeof(EFI_GUID); |
1455 |
mokbuffer = AllocatePool(mokbuffersize); |
|
41.2.43
by Matthew Garrett
Fix filesystem enrollment |
1456 |
|
1457 |
if (!mokbuffer) |
|
1458 |
goto out; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1459 |
|
1460 |
CertList = mokbuffer; |
|
41.2.152
by Gary Ching-Pang Lin
Merge signature.h into efiauthenticated.h and guid.h |
1461 |
CertList->SignatureType = X509_GUID; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1462 |
CertList->SignatureSize = 16 + datasize; |
1463 |
||
1464 |
memcpy(mokbuffer + sizeof(EFI_SIGNATURE_LIST) + 16, data, |
|
1465 |
datasize); |
|
1466 |
||
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1467 |
CertData = (EFI_SIGNATURE_DATA *)(((UINT8 *)mokbuffer) + |
1468 |
sizeof(EFI_SIGNATURE_LIST)); |
|
1469 |
}
|
|
1470 |
||
1471 |
CertList->SignatureListSize = mokbuffersize; |
|
1472 |
CertList->SignatureHeaderSize = 0; |
|
1473 |
CertData->SignatureOwner = shim_lock_guid; |
|
1474 |
||
1475 |
if (!hash) { |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1476 |
if (!verify_certificate(CertData->SignatureData, datasize)) |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1477 |
goto out; |
1478 |
}
|
|
1479 |
||
1480 |
mok_enrollment_prompt(mokbuffer, mokbuffersize, FALSE); |
|
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
1481 |
out: |
1482 |
if (mokbuffer) |
|
1483 |
FreePool(mokbuffer); |
|
1484 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1485 |
return status; |
1486 |
}
|
|
1487 |
||
1488 |
static void mok_hash_enroll(void) |
|
1489 |
{
|
|
1490 |
EFI_STATUS efi_status; |
|
1491 |
CHAR16 *file_name = NULL; |
|
1492 |
EFI_HANDLE im = NULL; |
|
1493 |
EFI_FILE *file = NULL; |
|
1494 |
UINTN filesize; |
|
1495 |
void *data; |
|
1496 |
||
1497 |
simple_file_selector(&im, (CHAR16 *[]){ |
|
1498 |
L"Select Binary", |
|
1499 |
L"", |
|
1500 |
L"The Selected Binary will have its hash Enrolled", |
|
1501 |
L"This means it will Subsequently Boot with no prompting", |
|
1502 |
L"Remember to make sure it is a genuine binary before Enroling its hash", |
|
1503 |
NULL
|
|
1504 |
}, L"\\", L"", &file_name); |
|
1505 |
||
1506 |
if (!file_name) |
|
1507 |
return; |
|
1508 |
||
1509 |
efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ); |
|
1510 |
||
1511 |
if (efi_status != EFI_SUCCESS) { |
|
1512 |
console_error(L"Unable to open file", efi_status); |
|
1513 |
return; |
|
1514 |
}
|
|
1515 |
||
1516 |
simple_file_read_all(file, &filesize, &data); |
|
1517 |
simple_file_close(file); |
|
1518 |
||
1519 |
if (!filesize) { |
|
1520 |
console_error(L"Unable to read file", efi_status); |
|
1521 |
return; |
|
1522 |
}
|
|
1523 |
||
1524 |
efi_status = enroll_file(data, filesize, TRUE); |
|
1525 |
||
1526 |
if (efi_status != EFI_SUCCESS) |
|
1527 |
console_error(L"Hash failed (did you select a valid EFI binary?)", efi_status); |
|
1528 |
||
1529 |
FreePool(data); |
|
1530 |
}
|
|
1531 |
||
41.2.147
by Gary Ching-Pang Lin
MokManager: check the suffix of the key file |
1532 |
static CHAR16 *der_suffix[] = { |
1533 |
L".cer", |
|
1534 |
L".der", |
|
1535 |
L".crt", |
|
1536 |
NULL
|
|
1537 |
};
|
|
1538 |
||
1539 |
static BOOLEAN check_der_suffix (CHAR16 *file_name) |
|
1540 |
{
|
|
1541 |
CHAR16 suffix[5]; |
|
1542 |
int i; |
|
1543 |
||
1544 |
if (!file_name || StrLen(file_name) <= 4) |
|
1545 |
return FALSE; |
|
1546 |
||
1547 |
suffix[0] = '\0'; |
|
1548 |
StrCat(suffix, file_name + StrLen(file_name) - 4); |
|
1549 |
||
1550 |
StrLwr (suffix); |
|
1551 |
for (i = 0; der_suffix[i] != NULL; i++) { |
|
1552 |
if (StrCmp(suffix, der_suffix[i]) == 0) { |
|
1553 |
return TRUE; |
|
1554 |
}
|
|
1555 |
}
|
|
1556 |
||
1557 |
return FALSE; |
|
1558 |
}
|
|
1559 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1560 |
static void mok_key_enroll(void) |
1561 |
{
|
|
1562 |
EFI_STATUS efi_status; |
|
1563 |
CHAR16 *file_name = NULL; |
|
1564 |
EFI_HANDLE im = NULL; |
|
1565 |
EFI_FILE *file = NULL; |
|
1566 |
UINTN filesize; |
|
1567 |
void *data; |
|
1568 |
||
1569 |
simple_file_selector(&im, (CHAR16 *[]){ |
|
1570 |
L"Select Key", |
|
1571 |
L"", |
|
1572 |
L"The selected key will be enrolled into the MOK database", |
|
1573 |
L"This means any binaries signed with it will be run without prompting", |
|
1574 |
L"Remember to make sure it is a genuine key before Enroling it", |
|
1575 |
NULL
|
|
1576 |
}, L"\\", L"", &file_name); |
|
1577 |
||
1578 |
if (!file_name) |
|
1579 |
return; |
|
1580 |
||
41.2.147
by Gary Ching-Pang Lin
MokManager: check the suffix of the key file |
1581 |
if (!check_der_suffix(file_name)) { |
1582 |
console_alertbox((CHAR16 *[]){ |
|
1583 |
L"Unsupported Format", |
|
1584 |
L"", |
|
1585 |
L"Only DER encoded certificate (*.cer/der/crt) is supported", |
|
1586 |
NULL}); |
|
1587 |
return; |
|
1588 |
}
|
|
1589 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1590 |
efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ); |
1591 |
||
1592 |
if (efi_status != EFI_SUCCESS) { |
|
1593 |
console_error(L"Unable to open file", efi_status); |
|
1594 |
return; |
|
1595 |
}
|
|
1596 |
||
1597 |
simple_file_read_all(file, &filesize, &data); |
|
1598 |
simple_file_close(file); |
|
1599 |
||
1600 |
if (!filesize) { |
|
1601 |
console_error(L"Unable to read file", efi_status); |
|
1602 |
return; |
|
1603 |
}
|
|
1604 |
||
1605 |
enroll_file(data, filesize, FALSE); |
|
1606 |
FreePool(data); |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1607 |
}
|
1608 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1609 |
static BOOLEAN verify_pw(BOOLEAN *protected) |
41.3.5
by Matthew Garrett
Add MOK password auth |
1610 |
{
|
1611 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
1612 |
EFI_STATUS efi_status; |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1613 |
SIMPLE_TEXT_OUTPUT_MODE SavedMode; |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1614 |
UINT8 pwhash[PASSWORD_CRYPT_SIZE]; |
1615 |
UINTN size = PASSWORD_CRYPT_SIZE; |
|
41.3.5
by Matthew Garrett
Add MOK password auth |
1616 |
UINT32 attributes; |
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1617 |
CHAR16 *message[2]; |
1618 |
||
1619 |
*protected = FALSE; |
|
41.3.5
by Matthew Garrett
Add MOK password auth |
1620 |
|
1621 |
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore", |
|
1622 |
&shim_lock_guid, &attributes, &size, |
|
1623 |
pwhash); |
|
1624 |
||
1625 |
/*
|
|
1626 |
* If anything can attack the password it could just set it to a
|
|
1627 |
* known value, so there's no safety advantage in failing to validate
|
|
1628 |
* purely because of a failure to read the variable
|
|
1629 |
*/
|
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1630 |
if (efi_status != EFI_SUCCESS || |
1631 |
(size != SHA256_DIGEST_SIZE && size != PASSWORD_CRYPT_SIZE)) |
|
41.3.5
by Matthew Garrett
Add MOK password auth |
1632 |
return TRUE; |
1633 |
||
1634 |
if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) |
|
1635 |
return TRUE; |
|
1636 |
||
41.3.8
by Matthew Garrett
Clear screen before prompting |
1637 |
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); |
1638 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1639 |
/* Draw the background */
|
1640 |
console_save_and_set_mode(&SavedMode); |
|
1641 |
message[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR); |
|
1642 |
message[1] = NULL; |
|
1643 |
console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1); |
|
1644 |
FreePool(message[0]); |
|
1645 |
console_restore_mode(&SavedMode); |
|
1646 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1647 |
if (size == PASSWORD_CRYPT_SIZE) { |
1648 |
efi_status = match_password((PASSWORD_CRYPT *)pwhash, NULL, 0, |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1649 |
NULL, L"Enter MOK password:"); |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1650 |
} else { |
1651 |
efi_status = match_password(NULL, NULL, 0, pwhash, |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1652 |
L"Enter MOK password:"); |
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1653 |
}
|
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
1654 |
if (efi_status != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1655 |
console_notify(L"Password limit reached"); |
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
1656 |
return FALSE; |
41.3.5
by Matthew Garrett
Add MOK password auth |
1657 |
}
|
1658 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1659 |
*protected = TRUE; |
1660 |
||
41.2.69
by Gary Ching-Pang Lin
Add a general function for password matching |
1661 |
return TRUE; |
41.3.5
by Matthew Garrett
Add MOK password auth |
1662 |
}
|
1663 |
||
41.2.138
by Gary Ching-Pang Lin
MokManager: draw the countdown screen |
1664 |
static int draw_countdown() |
1665 |
{
|
|
1666 |
SIMPLE_TEXT_OUTPUT_MODE SavedMode; |
|
1667 |
EFI_INPUT_KEY key; |
|
1668 |
EFI_STATUS status; |
|
1669 |
UINTN cols, rows; |
|
1670 |
CHAR16 *title[2]; |
|
1671 |
CHAR16 *message = L"Press any key to perform MOK management"; |
|
1672 |
int timeout = 10, wait = 10000000; |
|
1673 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1674 |
console_save_and_set_mode (&SavedMode); |
41.2.138
by Gary Ching-Pang Lin
MokManager: draw the countdown screen |
1675 |
|
1676 |
title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR); |
|
1677 |
title[1] = NULL; |
|
1678 |
||
1679 |
console_print_box_at(title, -1, 0, 0, -1, -1, 1, 1); |
|
1680 |
||
1681 |
uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, |
|
1682 |
ST->ConOut->Mode->Mode, &cols, &rows); |
|
1683 |
||
1684 |
PrintAt((cols - StrLen(message))/2, rows/2, message); |
|
1685 |
while (1) { |
|
1686 |
if (timeout > 1) |
|
1687 |
PrintAt(2, rows - 3, L"Booting in %d seconds ", timeout); |
|
1688 |
else if (timeout) |
|
1689 |
PrintAt(2, rows - 3, L"Booting in %d second ", timeout); |
|
1690 |
||
1691 |
status = WaitForSingleEvent(ST->ConIn->WaitForKey, wait); |
|
1692 |
||
1693 |
if (status != EFI_TIMEOUT) { |
|
1694 |
/* Clear the key in the queue */
|
|
1695 |
uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, |
|
1696 |
ST->ConIn, &key); |
|
1697 |
break; |
|
1698 |
}
|
|
1699 |
||
1700 |
timeout--; |
|
1701 |
if (!timeout) |
|
1702 |
break; |
|
1703 |
}
|
|
1704 |
||
1705 |
FreePool(title[0]); |
|
1706 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1707 |
console_restore_mode(&SavedMode); |
41.2.138
by Gary Ching-Pang Lin
MokManager: draw the countdown screen |
1708 |
|
1709 |
return timeout; |
|
1710 |
}
|
|
1711 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1712 |
typedef enum { |
1713 |
MOK_CONTINUE_BOOT, |
|
1714 |
MOK_RESET_MOK, |
|
1715 |
MOK_ENROLL_MOK, |
|
1716 |
MOK_DELETE_MOK, |
|
1717 |
MOK_CHANGE_SB, |
|
1718 |
MOK_SET_PW, |
|
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1719 |
MOK_CHANGE_DB, |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1720 |
MOK_KEY_ENROLL, |
1721 |
MOK_HASH_ENROLL
|
|
1722 |
} mok_menu_item; |
|
1723 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1724 |
static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, |
1725 |
void *MokNew, UINTN MokNewSize, |
|
1726 |
void *MokDel, UINTN MokDelSize, |
|
1727 |
void *MokSB, UINTN MokSBSize, |
|
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1728 |
void *MokPW, UINTN MokPWSize, |
1729 |
void *MokDB, UINTN MokDBSize) |
|
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
1730 |
{
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1731 |
CHAR16 **menu_strings; |
1732 |
mok_menu_item *menu_item; |
|
1733 |
int choice = 0; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1734 |
UINT32 MokAuth = 0; |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1735 |
UINT32 MokDelAuth = 0; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1736 |
UINTN menucount = 3, i = 0; |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1737 |
EFI_STATUS efi_status; |
1738 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1739 |
UINT8 auth[PASSWORD_CRYPT_SIZE]; |
1740 |
UINTN auth_size = PASSWORD_CRYPT_SIZE; |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1741 |
UINT32 attributes; |
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1742 |
BOOLEAN protected; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1743 |
EFI_STATUS ret = EFI_SUCCESS; |
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1744 |
|
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1745 |
if (verify_pw(&protected) == FALSE) |
41.3.5
by Matthew Garrett
Add MOK password auth |
1746 |
return EFI_ACCESS_DENIED; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1747 |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1748 |
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth", |
1749 |
&shim_lock_guid, |
|
1750 |
&attributes, &auth_size, auth); |
|
1751 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1752 |
if ((efi_status == EFI_SUCCESS) && |
1753 |
(auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE)) |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1754 |
MokAuth = 1; |
1755 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1756 |
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth", |
1757 |
&shim_lock_guid, |
|
1758 |
&attributes, &auth_size, auth); |
|
1759 |
||
41.2.127
by Gary Ching-Pang Lin
MokManager: support crypt() password hash |
1760 |
if ((efi_status == EFI_SUCCESS) && |
1761 |
(auth_size == SHA256_DIGEST_SIZE || auth_size == PASSWORD_CRYPT_SIZE)) |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1762 |
MokDelAuth = 1; |
1763 |
||
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1764 |
if (MokNew || MokAuth) |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1765 |
menucount++; |
1766 |
||
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1767 |
if (MokDel || MokDelAuth) |
1768 |
menucount++; |
|
1769 |
||
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1770 |
if (MokSB) |
1771 |
menucount++; |
|
1772 |
||
41.3.5
by Matthew Garrett
Add MOK password auth |
1773 |
if (MokPW) |
1774 |
menucount++; |
|
1775 |
||
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1776 |
if (MokDB) |
1777 |
menucount++; |
|
1778 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1779 |
menu_strings = AllocateZeroPool(sizeof(CHAR16 *) * (menucount + 1)); |
1780 |
||
1781 |
if (!menu_strings) |
|
1782 |
return EFI_OUT_OF_RESOURCES; |
|
1783 |
||
1784 |
menu_item = AllocateZeroPool(sizeof(mok_menu_item) * menucount); |
|
1785 |
||
1786 |
if (!menu_item) { |
|
1787 |
FreePool(menu_strings); |
|
1788 |
return EFI_OUT_OF_RESOURCES; |
|
1789 |
}
|
|
1790 |
||
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1791 |
menu_strings[i] = L"Continue boot"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1792 |
menu_item[i] = MOK_CONTINUE_BOOT; |
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
1793 |
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1794 |
i++; |
41.2.37
by Matthew Garrett
Fix menu items |
1795 |
|
41.2.56
by Matthew Garrett
Switch to using db format for MokList and MokNew |
1796 |
if (MokNew || MokAuth) { |
1797 |
if (!MokNew) { |
|
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1798 |
menu_strings[i] = L"Reset MOK"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1799 |
menu_item[i] = MOK_RESET_MOK; |
41.2.37
by Matthew Garrett
Fix menu items |
1800 |
} else { |
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1801 |
menu_strings[i] = L"Enroll MOK"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1802 |
menu_item[i] = MOK_ENROLL_MOK; |
41.2.37
by Matthew Garrett
Fix menu items |
1803 |
}
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1804 |
i++; |
1805 |
}
|
|
1806 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1807 |
if (MokDel || MokDelAuth) { |
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1808 |
menu_strings[i] = L"Delete MOK"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1809 |
menu_item[i] = MOK_DELETE_MOK; |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1810 |
i++; |
1811 |
}
|
|
1812 |
||
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1813 |
if (MokSB) { |
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1814 |
menu_strings[i] = L"Change Secure Boot state"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1815 |
menu_item[i] = MOK_CHANGE_SB; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1816 |
i++; |
1817 |
}
|
|
1818 |
||
41.3.5
by Matthew Garrett
Add MOK password auth |
1819 |
if (MokPW) { |
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1820 |
menu_strings[i] = L"Set MOK password"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1821 |
menu_item[i] = MOK_SET_PW; |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1822 |
i++; |
1823 |
}
|
|
1824 |
||
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1825 |
if (MokDB) { |
1826 |
menu_strings[i] = L"Change DB state"; |
|
1827 |
menu_item[i] = MOK_CHANGE_DB; |
|
1828 |
i++; |
|
1829 |
}
|
|
1830 |
||
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1831 |
menu_strings[i] = L"Enroll key from disk"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1832 |
menu_item[i] = MOK_KEY_ENROLL; |
1833 |
i++; |
|
1834 |
||
41.2.137
by Gary Ching-Pang Lin
MokManager: Remove the unnecessary string duplication |
1835 |
menu_strings[i] = L"Enroll hash from disk"; |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1836 |
menu_item[i] = MOK_HASH_ENROLL; |
1837 |
i++; |
|
1838 |
||
1839 |
menu_strings[i] = NULL; |
|
1840 |
||
41.2.140
by Gary Ching-Pang Lin
MokManager: enhance the password prompt |
1841 |
if (protected == FALSE && draw_countdown() == 0) |
41.2.138
by Gary Ching-Pang Lin
MokManager: draw the countdown screen |
1842 |
goto out; |
1843 |
||
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1844 |
while (choice >= 0) { |
1845 |
choice = console_select((CHAR16 *[]){ L"Perform MOK management", NULL }, |
|
1846 |
menu_strings, 0); |
|
1847 |
||
1848 |
if (choice < 0) |
|
1849 |
goto out; |
|
1850 |
||
1851 |
switch (menu_item[choice]) { |
|
1852 |
case MOK_CONTINUE_BOOT: |
|
1853 |
goto out; |
|
1854 |
case MOK_RESET_MOK: |
|
1855 |
mok_reset_prompt(); |
|
1856 |
break; |
|
1857 |
case MOK_ENROLL_MOK: |
|
1858 |
mok_enrollment_prompt(MokNew, MokNewSize, TRUE); |
|
1859 |
break; |
|
1860 |
case MOK_DELETE_MOK: |
|
1861 |
mok_deletion_prompt(MokDel, MokDelSize); |
|
1862 |
break; |
|
1863 |
case MOK_CHANGE_SB: |
|
1864 |
mok_sb_prompt(MokSB, MokSBSize); |
|
1865 |
break; |
|
1866 |
case MOK_SET_PW: |
|
1867 |
mok_pw_prompt(MokPW, MokPWSize); |
|
1868 |
break; |
|
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1869 |
case MOK_CHANGE_DB: |
1870 |
mok_db_prompt(MokDB, MokDBSize); |
|
1871 |
break; |
|
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1872 |
case MOK_KEY_ENROLL: |
1873 |
mok_key_enroll(); |
|
1874 |
break; |
|
1875 |
case MOK_HASH_ENROLL: |
|
1876 |
mok_hash_enroll(); |
|
1877 |
break; |
|
1878 |
}
|
|
1879 |
}
|
|
1880 |
||
1881 |
out: |
|
1882 |
console_reset(); |
|
1883 |
||
1884 |
FreePool(menu_strings); |
|
1885 |
||
1886 |
if (menu_item) |
|
1887 |
FreePool(menu_item); |
|
1888 |
||
1889 |
return ret; |
|
41.2.34
by Matthew Garrett
Add filesystem browsing and enrollment |
1890 |
}
|
1891 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
1892 |
static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) |
1893 |
{
|
|
1894 |
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; |
|
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1895 |
UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0, |
1896 |
MokDBSize = 0; |
|
41.2.11
by Gary Ching-Pang Lin
Simplify the key management |
1897 |
void *MokNew = NULL; |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1898 |
void *MokDel = NULL; |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1899 |
void *MokSB = NULL; |
41.3.5
by Matthew Garrett
Add MOK password auth |
1900 |
void *MokPW = NULL; |
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1901 |
void *MokDB = NULL; |
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1902 |
EFI_STATUS status; |
1903 |
||
1904 |
status = get_variable(L"MokNew", (UINT8 **)&MokNew, &MokNewSize, |
|
1905 |
shim_lock_guid); |
|
1906 |
if (status == EFI_SUCCESS) { |
|
41.2.27
by Gary Ching-Pang Lin
Use LibDeleteVariable in gnu-efi |
1907 |
if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1908 |
console_notify(L"Failed to delete MokNew"); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
1909 |
}
|
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1910 |
} else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { |
1911 |
console_error(L"Could not retrieve MokNew", status); |
|
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
1912 |
}
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1913 |
|
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1914 |
status = get_variable(L"MokDel", (UINT8 **)&MokDel, &MokDelSize, |
1915 |
shim_lock_guid); |
|
1916 |
if (status == EFI_SUCCESS) { |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1917 |
if (LibDeleteVariable(L"MokDel", &shim_lock_guid) != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1918 |
console_notify(L"Failed to delete MokDel"); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1919 |
}
|
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1920 |
} else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { |
1921 |
console_error(L"Could not retrieve MokDel", status); |
|
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1922 |
}
|
1923 |
||
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1924 |
status = get_variable(L"MokSB", (UINT8 **)&MokSB, &MokSBSize, |
1925 |
shim_lock_guid); |
|
1926 |
if (status == EFI_SUCCESS) { |
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1927 |
if (LibDeleteVariable(L"MokSB", &shim_lock_guid) != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1928 |
console_notify(L"Failed to delete MokSB"); |
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1929 |
}
|
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1930 |
} else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { |
1931 |
console_error(L"Could not retrieve MokSB", status); |
|
41.3.2
by Matthew Garrett
Add support for disabling signature verification |
1932 |
}
|
41.3.5
by Matthew Garrett
Add MOK password auth |
1933 |
|
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1934 |
status = get_variable(L"MokPW", (UINT8 **)&MokPW, &MokPWSize, |
1935 |
shim_lock_guid); |
|
1936 |
if (status == EFI_SUCCESS) { |
|
41.3.5
by Matthew Garrett
Add MOK password auth |
1937 |
if (LibDeleteVariable(L"MokPW", &shim_lock_guid) != EFI_SUCCESS) { |
41.2.122
by Peter Jones
Port MokManager to Linux Foundation loader UI code |
1938 |
console_notify(L"Failed to delete MokPW"); |
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1939 |
}
|
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1940 |
} else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { |
1941 |
console_error(L"Could not retrieve MokPW", status); |
|
1942 |
}
|
|
1943 |
||
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1944 |
status = get_variable(L"MokDB", (UINT8 **)&MokDB, &MokDBSize, |
1945 |
shim_lock_guid); |
|
1946 |
if (status == EFI_SUCCESS) { |
|
1947 |
if (LibDeleteVariable(L"MokDB", &shim_lock_guid) != EFI_SUCCESS) { |
|
1948 |
console_notify(L"Failed to delete MokDB"); |
|
1949 |
}
|
|
1950 |
} else if (EFI_ERROR(status) && status != EFI_NOT_FOUND) { |
|
1951 |
console_error(L"Could not retrieve MokDB", status); |
|
1952 |
}
|
|
1953 |
||
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1954 |
enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize, |
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1955 |
MokSB, MokSBSize, MokPW, MokPWSize, MokDB, MokDBSize); |
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1956 |
|
1957 |
if (MokNew) |
|
41.3.5
by Matthew Garrett
Add MOK password auth |
1958 |
FreePool (MokNew); |
41.2.156
by Peter Jones
Don't use LibGetVariable(), since it doesn't give us real error codes. |
1959 |
|
1960 |
if (MokDel) |
|
1961 |
FreePool (MokDel); |
|
1962 |
||
1963 |
if (MokSB) |
|
1964 |
FreePool (MokSB); |
|
1965 |
||
1966 |
if (MokPW) |
|
1967 |
FreePool (MokPW); |
|
0.1.5
by Steve Langasek
Import upstream version 0.7 |
1968 |
|
41.2.171
by Josh Boyer
Add support for disabling db for verification |
1969 |
if (MokDB) |
1970 |
FreePool (MokDB); |
|
1971 |
||
41.2.27
by Gary Ching-Pang Lin
Use LibDeleteVariable in gnu-efi |
1972 |
LibDeleteVariable(L"MokAuth", &shim_lock_guid); |
41.2.71
by Gary Ching-Pang Lin
Add support for deleting specific keys |
1973 |
LibDeleteVariable(L"MokDelAuth", &shim_lock_guid); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
1974 |
|
1975 |
return EFI_SUCCESS; |
|
1976 |
}
|
|
1977 |
||
41.3.12
by Matthew Garrett
Update image validation enable/disable |
1978 |
static EFI_STATUS setup_rand (void) |
1979 |
{
|
|
1980 |
EFI_TIME time; |
|
1981 |
EFI_STATUS efi_status; |
|
1982 |
UINT64 seed; |
|
1983 |
BOOLEAN status; |
|
1984 |
||
1985 |
efi_status = uefi_call_wrapper(RT->GetTime, 2, &time, NULL); |
|
1986 |
||
1987 |
if (efi_status != EFI_SUCCESS) |
|
1988 |
return efi_status; |
|
1989 |
||
1990 |
seed = ((UINT64)time.Year << 48) | ((UINT64)time.Month << 40) | |
|
1991 |
((UINT64)time.Day << 32) | ((UINT64)time.Hour << 24) | |
|
1992 |
((UINT64)time.Minute << 16) | ((UINT64)time.Second << 8) | |
|
1993 |
((UINT64)time.Daylight); |
|
1994 |
||
1995 |
status = RandomSeed((UINT8 *)&seed, sizeof(seed)); |
|
1996 |
||
1997 |
if (!status) |
|
1998 |
return EFI_ABORTED; |
|
1999 |
||
2000 |
return EFI_SUCCESS; |
|
2001 |
}
|
|
2002 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
2003 |
EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab) |
2004 |
{
|
|
2005 |
EFI_STATUS efi_status; |
|
2006 |
||
2007 |
InitializeLib(image_handle, systab); |
|
2008 |
||
41.2.119
by Peter Jones
MokManager needs to disable the graphics console. |
2009 |
setup_console(1); |
2010 |
||
41.3.12
by Matthew Garrett
Update image validation enable/disable |
2011 |
setup_rand(); |
2012 |
||
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
2013 |
efi_status = check_mok_request(image_handle); |
2014 |
||
41.2.119
by Peter Jones
MokManager needs to disable the graphics console. |
2015 |
setup_console(0); |
41.2.7
by Gary Ching-Pang Lin
Add a separate efi application to manage MOKs |
2016 |
return efi_status; |
2017 |
}
|