Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2020 IBM Corp. */
3 : : #ifndef pr_fmt
4 : : #define pr_fmt(fmt) "EDK2_COMPAT: " fmt
5 : : #endif
6 : :
7 : : #include <opal.h>
8 : : #include <string.h>
9 : : #include <time.h>
10 : : #include <unistd.h>
11 : : #include <stdint.h>
12 : : #include <ccan/endian/endian.h>
13 : : #include <mbedtls/error.h>
14 : : #include <mbedtls/oid.h>
15 : : #include <device.h>
16 : : #include <assert.h>
17 : : #include "libstb/crypto/pkcs7/pkcs7.h"
18 : : #include "edk2.h"
19 : : #include "../secvar.h"
20 : : #include "edk2-compat-process.h"
21 : :
22 : : bool setup_mode;
23 : :
24 : 12 : int update_variable_in_bank(struct secvar *update_var, const char *data,
25 : : const uint64_t dsize, struct list_head *bank)
26 : : {
27 : : struct secvar *var;
28 : :
29 : 12 : var = find_secvar(update_var->key, update_var->key_len, bank);
30 : 12 : if (!var)
31 : 0 : return OPAL_EMPTY;
32 : :
33 : : /* Reallocate the data memory, if there is change in data size */
34 : 12 : if (var->data_size < dsize)
35 : 9 : if (realloc_secvar(var, dsize))
36 : 0 : return OPAL_NO_MEM;
37 : :
38 : 12 : if (dsize && data)
39 : 10 : memcpy(var->data, data, dsize);
40 : 12 : var->data_size = dsize;
41 : :
42 : : /* Clear the volatile bit only if updated with positive data size */
43 : 12 : if (dsize)
44 : 10 : var->flags &= ~SECVAR_FLAG_VOLATILE;
45 : : else
46 : 2 : var->flags |= SECVAR_FLAG_VOLATILE;
47 : :
48 : 12 : if (key_equals(update_var->key, "PK")
49 : 7 : || key_equals(update_var->key, "HWKH")
50 : 7 : || key_equals(update_var->key, "TS"))
51 : 5 : var->flags |= SECVAR_FLAG_PROTECTED;
52 : :
53 : 12 : return 0;
54 : : }
55 : :
56 : : /* Expand char to wide character size */
57 : 14 : static char *char_to_wchar(const char *key, const size_t keylen)
58 : : {
59 : : int i;
60 : : char *str;
61 : :
62 : 14 : str = zalloc(keylen * 2);
63 : 14 : if (!str)
64 : 0 : return NULL;
65 : :
66 : 46 : for (i = 0; i < keylen*2; key++) {
67 : 32 : str[i++] = *key;
68 : 32 : str[i++] = '\0';
69 : : }
70 : :
71 : 14 : return str;
72 : : }
73 : :
74 : : /* Returns the authority that can sign the given key update */
75 : 14 : static void get_key_authority(const char *ret[3], const char *key)
76 : : {
77 : 14 : int i = 0;
78 : :
79 : 14 : if (key_equals(key, "PK")) {
80 : 2 : ret[i++] = "PK";
81 : 12 : } else if (key_equals(key, "KEK")) {
82 : 3 : ret[i++] = "PK";
83 : 9 : } else if (key_equals(key, "db") || key_equals(key, "dbx")) {
84 : 9 : ret[i++] = "KEK";
85 : 9 : ret[i++] = "PK";
86 : : }
87 : :
88 : 14 : ret[i] = NULL;
89 : 14 : }
90 : :
91 : 92 : static EFI_SIGNATURE_LIST* get_esl_signature_list(const char *buf, size_t buflen)
92 : : {
93 : 92 : EFI_SIGNATURE_LIST *list = NULL;
94 : :
95 : 92 : if (buflen < sizeof(EFI_SIGNATURE_LIST) || !buf)
96 : 0 : return NULL;
97 : :
98 : 92 : list = (EFI_SIGNATURE_LIST *)buf;
99 : :
100 : 92 : return list;
101 : : }
102 : :
103 : : /* Returns the size of the complete ESL. */
104 : 16 : static int32_t get_esl_signature_list_size(const char *buf, const size_t buflen)
105 : : {
106 : 16 : EFI_SIGNATURE_LIST *list = get_esl_signature_list(buf, buflen);
107 : :
108 : 16 : if (!list)
109 : 0 : return OPAL_PARAMETER;
110 : :
111 : 16 : return le32_to_cpu(list->SignatureListSize);
112 : : }
113 : :
114 : : /*
115 : : * Copies the certificate from the ESL into cert buffer and returns the size
116 : : * of the certificate
117 : : */
118 : 46 : static int get_esl_cert(const char *buf, const size_t buflen, char **cert)
119 : : {
120 : : size_t sig_data_offset;
121 : : size_t size;
122 : 46 : EFI_SIGNATURE_LIST *list = get_esl_signature_list(buf, buflen);
123 : :
124 : 46 : if (!list)
125 : 0 : return OPAL_PARAMETER;
126 : :
127 : 46 : assert(cert != NULL);
128 : :
129 : 46 : if (le32_to_cpu(list->SignatureSize) <= sizeof(uuid_t))
130 : 1 : return OPAL_PARAMETER;
131 : :
132 : 45 : size = le32_to_cpu(list->SignatureSize) - sizeof(uuid_t);
133 : :
134 : 45 : prlog(PR_DEBUG,"size of signature list size is %u\n",
135 : : le32_to_cpu(list->SignatureListSize));
136 : 45 : prlog(PR_DEBUG, "size of signature header size is %u\n",
137 : : le32_to_cpu(list->SignatureHeaderSize));
138 : 45 : prlog(PR_DEBUG, "size of signature size is %u\n",
139 : : le32_to_cpu(list->SignatureSize));
140 : :
141 : 45 : sig_data_offset = sizeof(EFI_SIGNATURE_LIST)
142 : 45 : + le32_to_cpu(list->SignatureHeaderSize)
143 : : + 16 * sizeof(uint8_t);
144 : :
145 : : /* Ensure this ESL does not overflow the bounds of the buffer */
146 : 45 : if (sig_data_offset + size > buflen) {
147 : 2 : prlog(PR_ERR, "Number of bytes of ESL data is less than size specified\n");
148 : 2 : return OPAL_PARAMETER;
149 : : }
150 : :
151 : 43 : *cert = zalloc(size);
152 : 43 : if (!(*cert))
153 : 0 : return OPAL_NO_MEM;
154 : :
155 : : /* Since buf can have more than one ESL, copy only the size calculated
156 : : * to return single ESL */
157 : 43 : memcpy(*cert, buf + sig_data_offset, size);
158 : :
159 : 43 : return size;
160 : : }
161 : :
162 : : /*
163 : : * Extracts size of the PKCS7 signed data embedded in the
164 : : * struct Authentication 2 Descriptor Header.
165 : : */
166 : 50 : static size_t get_pkcs7_len(const struct efi_variable_authentication_2 *auth)
167 : : {
168 : : uint32_t dw_length;
169 : : size_t size;
170 : :
171 : 50 : assert(auth != NULL);
172 : :
173 : 50 : dw_length = le32_to_cpu(auth->auth_info.hdr.dw_length);
174 : 50 : size = dw_length - (sizeof(auth->auth_info.hdr.dw_length)
175 : : + sizeof(auth->auth_info.hdr.w_revision)
176 : : + sizeof(auth->auth_info.hdr.w_certificate_type)
177 : : + sizeof(auth->auth_info.cert_type));
178 : :
179 : 50 : return size;
180 : : }
181 : :
182 : 32 : int get_auth_descriptor2(const void *buf, const size_t buflen, void **auth_buffer)
183 : : {
184 : 32 : const struct efi_variable_authentication_2 *auth = buf;
185 : : int auth_buffer_size;
186 : : size_t len;
187 : :
188 : 32 : assert(auth_buffer != NULL);
189 : 32 : if (buflen < sizeof(struct efi_variable_authentication_2)
190 : 32 : || !buf)
191 : 0 : return OPAL_PARAMETER;
192 : :
193 : 32 : len = get_pkcs7_len(auth);
194 : : /* pkcs7 content length cannot be greater than buflen */
195 : 32 : if (len > buflen)
196 : 0 : return OPAL_PARAMETER;
197 : :
198 : 32 : auth_buffer_size = sizeof(auth->timestamp) + sizeof(auth->auth_info.hdr)
199 : 32 : + sizeof(auth->auth_info.cert_type) + len;
200 : :
201 : 32 : if (auth_buffer_size > buflen)
202 : 1 : return OPAL_PARAMETER;
203 : :
204 : 31 : *auth_buffer = zalloc(auth_buffer_size);
205 : 31 : if (!(*auth_buffer))
206 : 0 : return OPAL_NO_MEM;
207 : :
208 : : /*
209 : : * Data = auth descriptor + new ESL data.
210 : : * Extracts only the auth descriptor from data.
211 : : */
212 : 31 : memcpy(*auth_buffer, buf, auth_buffer_size);
213 : :
214 : 31 : return auth_buffer_size;
215 : : }
216 : :
217 : 20 : static bool validate_cert(char *signing_cert, int signing_cert_size)
218 : : {
219 : : mbedtls_x509_crt x509;
220 : 20 : char *x509_buf = NULL;
221 : : int rc;
222 : :
223 : 20 : mbedtls_x509_crt_init(&x509);
224 : 20 : rc = mbedtls_x509_crt_parse(&x509, signing_cert, signing_cert_size);
225 : :
226 : : /* If failure in parsing the certificate, exit */
227 : 20 : if(rc) {
228 : 0 : prlog(PR_ERR, "X509 certificate parsing failed %04x\n", rc);
229 : 0 : return false;
230 : : }
231 : :
232 : 20 : x509_buf = zalloc(CERT_BUFFER_SIZE);
233 : 20 : rc = mbedtls_x509_crt_info(x509_buf, CERT_BUFFER_SIZE, "CRT:", &x509);
234 : :
235 : 20 : mbedtls_x509_crt_free(&x509);
236 : 20 : free(x509_buf);
237 : 20 : x509_buf = NULL;
238 : :
239 : : /* If failure in reading the certificate, exit */
240 : 20 : if (rc < 0)
241 : 0 : return false;
242 : :
243 : 20 : return true;
244 : : }
245 : :
246 : 6 : static bool validate_hash(uuid_t type, int size)
247 : : {
248 : 6 : if (uuid_equals(&type, &EFI_CERT_SHA1_GUID) && (size == 20))
249 : 0 : return true;
250 : :
251 : 6 : if (uuid_equals(&type, &EFI_CERT_SHA224_GUID) && (size == 28))
252 : 0 : return true;
253 : :
254 : 6 : if (uuid_equals(&type, &EFI_CERT_SHA256_GUID) && (size == 32))
255 : 1 : return true;
256 : :
257 : 5 : if (uuid_equals(&type, &EFI_CERT_SHA384_GUID) && (size == 48))
258 : 0 : return true;
259 : :
260 : 5 : if (uuid_equals(&type, &EFI_CERT_SHA512_GUID) && (size == 64))
261 : 1 : return true;
262 : :
263 : 4 : return false;
264 : : }
265 : :
266 : 28 : int validate_esl_list(const char *key, const char *esl, const size_t size)
267 : : {
268 : 28 : int count = 0;
269 : : int dsize;
270 : 28 : char *data = NULL;
271 : 28 : int eslvarsize = size;
272 : : int eslsize;
273 : 28 : int rc = OPAL_SUCCESS;
274 : 28 : EFI_SIGNATURE_LIST *list = NULL;
275 : :
276 : 50 : while (eslvarsize > 0) {
277 : 31 : prlog(PR_DEBUG, "esl var size is %d offset is %lu\n", eslvarsize, size - eslvarsize);
278 : 31 : if (eslvarsize < sizeof(EFI_SIGNATURE_LIST)) {
279 : 1 : prlog(PR_ERR, "ESL with size %d is too small\n", eslvarsize);
280 : 1 : rc = OPAL_PARAMETER;
281 : 1 : break;
282 : : }
283 : :
284 : : /* Check Supported ESL Type */
285 : 30 : list = get_esl_signature_list(esl, eslvarsize);
286 : :
287 : 30 : if (!list)
288 : 0 : return OPAL_PARAMETER;
289 : :
290 : : /* Calculate the size of the ESL */
291 : 30 : eslsize = le32_to_cpu(list->SignatureListSize);
292 : :
293 : : /* If could not extract the size */
294 : 30 : if (eslsize <= 0) {
295 : 0 : prlog(PR_ERR, "Invalid size of the ESL: %u\n",
296 : : le32_to_cpu(list->SignatureListSize));
297 : 0 : rc = OPAL_PARAMETER;
298 : 0 : break;
299 : : }
300 : :
301 : : /* Extract the certificate from the ESL */
302 : 30 : dsize = get_esl_cert(esl, eslvarsize, &data);
303 : 30 : if (dsize < 0) {
304 : 3 : rc = dsize;
305 : 3 : break;
306 : : }
307 : :
308 : 27 : if (key_equals(key, "dbx")) {
309 : 6 : if (!validate_hash(list->SignatureType, dsize)) {
310 : 4 : prlog(PR_ERR, "No valid hash is found\n");
311 : 4 : rc = OPAL_PARAMETER;
312 : 4 : break;
313 : : }
314 : : } else {
315 : 21 : if (!uuid_equals(&list->SignatureType, &EFI_CERT_X509_GUID)
316 : 20 : || !validate_cert(data, dsize)) {
317 : 1 : prlog(PR_ERR, "No valid cert is found\n");
318 : 1 : rc = OPAL_PARAMETER;
319 : 1 : break;
320 : : }
321 : : }
322 : :
323 : 22 : count++;
324 : :
325 : : /* Look for the next ESL */
326 : 22 : esl = esl + eslsize;
327 : 22 : eslvarsize = eslvarsize - eslsize;
328 : 22 : free(data);
329 : : /* Since we are going to allocate again in the next iteration */
330 : 22 : data = NULL;
331 : : }
332 : :
333 : 28 : if (rc == OPAL_SUCCESS) {
334 : 19 : if (key_equals(key, "PK") && (count > 1)) {
335 : 1 : prlog(PR_ERR, "PK can only be one\n");
336 : 1 : rc = OPAL_PARAMETER;
337 : : } else {
338 : 18 : rc = count;
339 : : }
340 : : }
341 : :
342 : 28 : free(data);
343 : :
344 : 28 : prlog(PR_INFO, "Total ESLs are %d\n", rc);
345 : 28 : return rc;
346 : : }
347 : :
348 : : /* Get the timestamp for the last update of the give key */
349 : 43 : static struct efi_time *get_last_timestamp(const char *key, char *last_timestamp)
350 : : {
351 : 43 : struct efi_time *timestamp = (struct efi_time*)last_timestamp;
352 : :
353 : 43 : if (!last_timestamp)
354 : 0 : return NULL;
355 : :
356 : 43 : if (key_equals(key, "PK"))
357 : 12 : return ×tamp[0];
358 : 31 : else if (key_equals(key, "KEK"))
359 : 11 : return ×tamp[1];
360 : 20 : else if (key_equals(key, "db"))
361 : 12 : return ×tamp[2];
362 : 8 : else if (key_equals(key, "dbx"))
363 : 8 : return ×tamp[3];
364 : : else
365 : 0 : return NULL;
366 : : }
367 : :
368 : 12 : int update_timestamp(const char *key, const struct efi_time *timestamp, char *last_timestamp)
369 : : {
370 : : struct efi_time *prev;
371 : :
372 : 12 : prev = get_last_timestamp(key, last_timestamp);
373 : 12 : if (prev == NULL)
374 : 0 : return OPAL_INTERNAL_ERROR;
375 : :
376 : : /* Update with new timestamp */
377 : 12 : memcpy(prev, timestamp, sizeof(struct efi_time));
378 : :
379 : 12 : prlog(PR_DEBUG, "updated prev year is %d month %d day %d\n",
380 : : le16_to_cpu(prev->year), prev->month, prev->day);
381 : :
382 : 12 : return OPAL_SUCCESS;
383 : : }
384 : :
385 : 62 : static uint64_t unpack_timestamp(const struct efi_time *timestamp)
386 : : {
387 : 62 : uint64_t val = 0;
388 : 62 : uint16_t year = le16_to_cpu(timestamp->year);
389 : :
390 : : /* pad1, nanosecond, timezone, daylight and pad2 are meant to be zero */
391 : 62 : val |= ((uint64_t) timestamp->pad1 & 0xFF) << 0;
392 : 62 : val |= ((uint64_t) timestamp->second & 0xFF) << (1*8);
393 : 62 : val |= ((uint64_t) timestamp->minute & 0xFF) << (2*8);
394 : 62 : val |= ((uint64_t) timestamp->hour & 0xFF) << (3*8);
395 : 62 : val |= ((uint64_t) timestamp->day & 0xFF) << (4*8);
396 : 62 : val |= ((uint64_t) timestamp->month & 0xFF) << (5*8);
397 : 62 : val |= ((uint64_t) year) << (6*8);
398 : :
399 : 62 : return val;
400 : : }
401 : :
402 : 31 : int check_timestamp(const char *key, const struct efi_time *timestamp,
403 : : char *last_timestamp)
404 : : {
405 : : struct efi_time *prev;
406 : : uint64_t new;
407 : : uint64_t last;
408 : :
409 : 31 : prev = get_last_timestamp(key, last_timestamp);
410 : 31 : if (prev == NULL)
411 : 0 : return OPAL_INTERNAL_ERROR;
412 : :
413 : 31 : prlog(PR_DEBUG, "timestamp year is %d month %d day %d\n",
414 : : le16_to_cpu(timestamp->year), timestamp->month,
415 : : timestamp->day);
416 : 31 : prlog(PR_DEBUG, "prev year is %d month %d day %d\n",
417 : : le16_to_cpu(prev->year), prev->month, prev->day);
418 : :
419 : 31 : new = unpack_timestamp(timestamp);
420 : 31 : last = unpack_timestamp(prev);
421 : :
422 : 31 : if (new > last)
423 : 28 : return OPAL_SUCCESS;
424 : :
425 : 3 : return OPAL_PERMISSION;
426 : : }
427 : :
428 : : /* Extract PKCS7 from the authentication header */
429 : 18 : static mbedtls_pkcs7* get_pkcs7(const struct efi_variable_authentication_2 *auth)
430 : : {
431 : 18 : char *checkpkcs7cert = NULL;
432 : : size_t len;
433 : 18 : mbedtls_pkcs7 *pkcs7 = NULL;
434 : : int rc;
435 : :
436 : 18 : len = get_pkcs7_len(auth);
437 : :
438 : 18 : pkcs7 = malloc(sizeof(struct mbedtls_pkcs7));
439 : 18 : if (!pkcs7)
440 : 0 : return NULL;
441 : :
442 : 18 : mbedtls_pkcs7_init(pkcs7);
443 : 18 : rc = mbedtls_pkcs7_parse_der( auth->auth_info.cert_data, len, pkcs7);
444 : 18 : if (rc <= 0) {
445 : 1 : prlog(PR_ERR, "Parsing pkcs7 failed %04x\n", rc);
446 : 1 : goto out;
447 : : }
448 : :
449 : 17 : checkpkcs7cert = zalloc(CERT_BUFFER_SIZE);
450 : 17 : if (!checkpkcs7cert)
451 : 0 : goto out;
452 : :
453 : 17 : rc = mbedtls_x509_crt_info(checkpkcs7cert, CERT_BUFFER_SIZE, "CRT:",
454 : 17 : &(pkcs7->signed_data.certs));
455 : 17 : if (rc < 0) {
456 : 0 : prlog(PR_ERR, "Failed to parse the certificate in PKCS7 structure\n");
457 : 0 : free(checkpkcs7cert);
458 : 0 : goto out;
459 : : }
460 : :
461 : 17 : prlog(PR_DEBUG, "%s \n", checkpkcs7cert);
462 : 17 : free(checkpkcs7cert);
463 : 17 : return pkcs7;
464 : :
465 : 1 : out:
466 : 1 : mbedtls_pkcs7_free(pkcs7);
467 : 1 : free(pkcs7);
468 : 1 : pkcs7 = NULL;
469 : 1 : return pkcs7;
470 : : }
471 : :
472 : : /* Verify the PKCS7 signature on the signed data. */
473 : 18 : static int verify_signature(const struct efi_variable_authentication_2 *auth,
474 : : const char *hash, const size_t hash_len,
475 : : const struct secvar *avar)
476 : : {
477 : 18 : mbedtls_pkcs7 *pkcs7 = NULL;
478 : : mbedtls_x509_crt x509;
479 : : mbedtls_md_type_t md_alg;
480 : 18 : char *signing_cert = NULL;
481 : 18 : char *x509_buf = NULL;
482 : : int signing_cert_size;
483 : 18 : int rc = 0;
484 : : char *errbuf;
485 : : int eslvarsize;
486 : : int eslsize;
487 : 18 : int offset = 0;
488 : :
489 : 18 : if (!auth)
490 : 0 : return OPAL_PARAMETER;
491 : :
492 : : /* Extract the pkcs7 from the auth structure */
493 : 18 : pkcs7 = get_pkcs7(auth);
494 : : /* Failure to parse pkcs7 implies bad input. */
495 : 18 : if (!pkcs7)
496 : 1 : return OPAL_PARAMETER;
497 : :
498 : : /*
499 : : * We only support sha256, which has a hash length of 32.
500 : : * If the alg is not sha256, then we should bail now.
501 : : */
502 : 17 : rc = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers,
503 : : &md_alg);
504 : 17 : if (rc != 0) {
505 : 0 : prlog(PR_ERR, "Failed to get the Digest Algorithm Identifier: %d\n", rc);
506 : 0 : rc = OPAL_PARAMETER;
507 : 0 : goto err_pkcs7;
508 : : }
509 : :
510 : 17 : if (md_alg != MBEDTLS_MD_SHA256) {
511 : 2 : prlog(PR_ERR, "Unexpected digest algorithm: expected %d (SHA-256), got %d\n",
512 : : MBEDTLS_MD_SHA256, md_alg);
513 : 2 : rc = OPAL_PARAMETER;
514 : 2 : goto err_pkcs7;
515 : : }
516 : :
517 : 15 : prlog(PR_INFO, "Load the signing certificate from the keystore");
518 : :
519 : 15 : eslvarsize = avar->data_size;
520 : :
521 : : /* Variable is not empty */
522 : 23 : while (eslvarsize > 0) {
523 : 17 : prlog(PR_DEBUG, "esl var size is %d offset is %d\n", eslvarsize, offset);
524 : 17 : if (eslvarsize < sizeof(EFI_SIGNATURE_LIST)) {
525 : 1 : rc = OPAL_INTERNAL_ERROR;
526 : 1 : prlog(PR_ERR, "ESL data is corrupted\n");
527 : 1 : break;
528 : : }
529 : :
530 : : /* Calculate the size of the ESL */
531 : 16 : eslsize = get_esl_signature_list_size(avar->data + offset,
532 : : eslvarsize);
533 : : /* If could not extract the size */
534 : 16 : if (eslsize <= 0) {
535 : 0 : rc = OPAL_PARAMETER;
536 : 0 : break;
537 : : }
538 : :
539 : : /* Extract the certificate from the ESL */
540 : 16 : signing_cert_size = get_esl_cert(avar->data + offset,
541 : : eslvarsize, &signing_cert);
542 : 16 : if (signing_cert_size < 0) {
543 : 0 : rc = signing_cert_size;
544 : 0 : break;
545 : : }
546 : :
547 : 16 : mbedtls_x509_crt_init(&x509);
548 : 16 : rc = mbedtls_x509_crt_parse(&x509,
549 : : signing_cert,
550 : : signing_cert_size);
551 : :
552 : : /* This should not happen, unless something corrupted in PNOR */
553 : 16 : if(rc) {
554 : 0 : prlog(PR_ERR, "X509 certificate parsing failed %04x\n", rc);
555 : 0 : rc = OPAL_INTERNAL_ERROR;
556 : 0 : break;
557 : : }
558 : :
559 : 16 : x509_buf = zalloc(CERT_BUFFER_SIZE);
560 : 16 : rc = mbedtls_x509_crt_info(x509_buf,
561 : : CERT_BUFFER_SIZE,
562 : : "CRT:",
563 : : &x509);
564 : :
565 : : /* This should not happen, unless something corrupted in PNOR */
566 : 16 : if (rc < 0) {
567 : 0 : free(x509_buf);
568 : 0 : rc = OPAL_INTERNAL_ERROR;
569 : 0 : break;
570 : : }
571 : :
572 : 16 : prlog(PR_INFO, "%s \n", x509_buf);
573 : 16 : free(x509_buf);
574 : 16 : x509_buf = NULL;
575 : :
576 : 16 : rc = mbedtls_pkcs7_signed_hash_verify(pkcs7, &x509, hash, hash_len);
577 : :
578 : : /* If you find a signing certificate, you are done */
579 : 16 : if (rc == 0) {
580 : 8 : prlog(PR_INFO, "Signature Verification passed\n");
581 : 8 : mbedtls_x509_crt_free(&x509);
582 : 8 : break;
583 : : } else {
584 : 8 : errbuf = zalloc(MBEDTLS_ERR_BUFFER_SIZE);
585 : 8 : mbedtls_strerror(rc, errbuf, MBEDTLS_ERR_BUFFER_SIZE);
586 : 8 : prlog(PR_ERR, "Signature Verification failed %02x %s\n",
587 : : rc, errbuf);
588 : 8 : free(errbuf);
589 : 8 : rc = OPAL_PERMISSION;
590 : : }
591 : :
592 : :
593 : : /* Look for the next ESL */
594 : 8 : offset = offset + eslsize;
595 : 8 : eslvarsize = eslvarsize - eslsize;
596 : 8 : mbedtls_x509_crt_free(&x509);
597 : 8 : free(signing_cert);
598 : : /* Since we are going to allocate again in the next iteration */
599 : 8 : signing_cert = NULL;
600 : :
601 : : }
602 : :
603 : 15 : free(signing_cert);
604 : 17 : err_pkcs7:
605 : 17 : mbedtls_pkcs7_free(pkcs7);
606 : 17 : free(pkcs7);
607 : :
608 : 17 : return rc;
609 : : }
610 : :
611 : : /*
612 : : * Create the hash of the buffer
613 : : * name || vendor guid || attributes || timestamp || newcontent
614 : : * which is submitted as signed by the user.
615 : : * Returns the sha256 hash, else NULL.
616 : : */
617 : 14 : static char *get_hash_to_verify(const char *key, const char *new_data,
618 : : const size_t new_data_size,
619 : : const struct efi_time *timestamp)
620 : : {
621 : 14 : le32 attr = cpu_to_le32(SECVAR_ATTRIBUTES);
622 : : size_t varlen;
623 : : char *wkey;
624 : : uuid_t guid;
625 : 14 : unsigned char *hash = NULL;
626 : : const mbedtls_md_info_t *md_info;
627 : : mbedtls_md_context_t ctx;
628 : : int rc;
629 : :
630 : 14 : md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
631 : 14 : mbedtls_md_init(&ctx);
632 : :
633 : 14 : rc = mbedtls_md_setup(&ctx, md_info, 0);
634 : 14 : if (rc)
635 : 0 : goto out;
636 : :
637 : 14 : rc = mbedtls_md_starts(&ctx);
638 : 14 : if (rc)
639 : 0 : goto out;
640 : :
641 : 14 : if (key_equals(key, "PK")
642 : 12 : || key_equals(key, "KEK"))
643 : 5 : guid = EFI_GLOBAL_VARIABLE_GUID;
644 : 9 : else if (key_equals(key, "db")
645 : 1 : || key_equals(key, "dbx"))
646 : 9 : guid = EFI_IMAGE_SECURITY_DATABASE_GUID;
647 : : else
648 : 0 : goto out;
649 : :
650 : : /* Expand char name to wide character width */
651 : 14 : varlen = strlen(key) * 2;
652 : 14 : wkey = char_to_wchar(key, strlen(key));
653 : 14 : rc = mbedtls_md_update(&ctx, wkey, varlen);
654 : 14 : free(wkey);
655 : 14 : if (rc)
656 : 0 : goto out;
657 : :
658 : 14 : rc = mbedtls_md_update(&ctx, (const unsigned char *)&guid, sizeof(guid));
659 : 14 : if (rc)
660 : 0 : goto out;
661 : :
662 : 14 : rc = mbedtls_md_update(&ctx, (const unsigned char *)&attr, sizeof(attr));
663 : 14 : if (rc)
664 : 0 : goto out;
665 : :
666 : 14 : rc = mbedtls_md_update(&ctx, (const unsigned char *)timestamp,
667 : : sizeof(struct efi_time));
668 : 14 : if (rc)
669 : 0 : goto out;
670 : :
671 : 14 : rc = mbedtls_md_update(&ctx, new_data, new_data_size);
672 : 14 : if (rc)
673 : 0 : goto out;
674 : :
675 : 14 : hash = zalloc(32);
676 : 14 : if (!hash)
677 : 0 : goto out;
678 : 14 : rc = mbedtls_md_finish(&ctx, hash);
679 : 14 : if (rc) {
680 : 0 : free(hash);
681 : 0 : hash = NULL;
682 : : }
683 : :
684 : 14 : out:
685 : 14 : mbedtls_md_free(&ctx);
686 : 14 : return hash;
687 : : }
688 : :
689 : 34 : bool is_pkcs7_sig_format(const void *data)
690 : : {
691 : 34 : const struct efi_variable_authentication_2 *auth = data;
692 : 34 : uuid_t pkcs7_guid = EFI_CERT_TYPE_PKCS7_GUID;
693 : :
694 : 34 : return !memcmp(&auth->auth_info.cert_type, &pkcs7_guid, 16);
695 : : }
696 : :
697 : 32 : int process_update(const struct secvar *update, char **newesl,
698 : : int *new_data_size, struct efi_time *timestamp,
699 : : struct list_head *bank, char *last_timestamp)
700 : : {
701 : 32 : struct efi_variable_authentication_2 *auth = NULL;
702 : 32 : void *auth_buffer = NULL;
703 : 32 : int auth_buffer_size = 0;
704 : : const char *key_authority[3];
705 : 32 : char *hash = NULL;
706 : 32 : struct secvar *avar = NULL;
707 : 32 : int rc = 0;
708 : : int i;
709 : :
710 : : /* We need to split data into authentication descriptor and new ESL */
711 : 32 : auth_buffer_size = get_auth_descriptor2(update->data,
712 : 32 : update->data_size,
713 : : &auth_buffer);
714 : 32 : if ((auth_buffer_size < 0)
715 : 31 : || (update->data_size < auth_buffer_size)) {
716 : 1 : prlog(PR_ERR, "Invalid auth buffer size\n");
717 : 1 : rc = auth_buffer_size;
718 : 1 : goto out;
719 : : }
720 : :
721 : 31 : auth = auth_buffer;
722 : :
723 : 31 : if (!timestamp) {
724 : 0 : rc = OPAL_INTERNAL_ERROR;
725 : 0 : goto out;
726 : : }
727 : :
728 : 31 : memcpy(timestamp, auth_buffer, sizeof(struct efi_time));
729 : :
730 : 31 : rc = check_timestamp(update->key, timestamp, last_timestamp);
731 : : /* Failure implies probably an older command being resubmitted */
732 : 31 : if (rc != OPAL_SUCCESS) {
733 : 3 : prlog(PR_ERR, "Timestamp verification failed for key %s\n", update->key);
734 : 3 : goto out;
735 : : }
736 : :
737 : : /* Calculate the size of new ESL data */
738 : 28 : *new_data_size = update->data_size - auth_buffer_size;
739 : 28 : if (*new_data_size < 0) {
740 : 0 : prlog(PR_ERR, "Invalid new ESL (new data content) size\n");
741 : 0 : rc = OPAL_PARAMETER;
742 : 0 : goto out;
743 : : }
744 : 28 : *newesl = zalloc(*new_data_size);
745 : 28 : if (!(*newesl)) {
746 : 0 : rc = OPAL_NO_MEM;
747 : 0 : goto out;
748 : : }
749 : 28 : memcpy(*newesl, update->data + auth_buffer_size, *new_data_size);
750 : :
751 : : /* Validate the new ESL is in right format */
752 : 28 : rc = validate_esl_list(update->key, *newesl, *new_data_size);
753 : 28 : if (rc < 0) {
754 : 10 : prlog(PR_ERR, "ESL validation failed for key %s with error %04x\n",
755 : : update->key, rc);
756 : 10 : goto out;
757 : : }
758 : :
759 : 18 : if (setup_mode) {
760 : 4 : rc = OPAL_SUCCESS;
761 : 4 : goto out;
762 : : }
763 : :
764 : : /* Prepare the data to be verified */
765 : 14 : hash = get_hash_to_verify(update->key, *newesl, *new_data_size,
766 : : timestamp);
767 : 14 : if (!hash) {
768 : 0 : rc = OPAL_INTERNAL_ERROR;
769 : 0 : goto out;
770 : : }
771 : :
772 : : /* Get the authority to verify the signature */
773 : 14 : get_key_authority(key_authority, update->key);
774 : :
775 : : /*
776 : : * Try for all the authorities that are allowed to sign.
777 : : * For eg. db/dbx can be signed by both PK or KEK
778 : : */
779 : 27 : for (i = 0; key_authority[i] != NULL; i++) {
780 : 21 : prlog(PR_DEBUG, "key is %s\n", update->key);
781 : 21 : prlog(PR_DEBUG, "key authority is %s\n", key_authority[i]);
782 : 21 : avar = find_secvar(key_authority[i],
783 : 21 : strlen(key_authority[i]) + 1,
784 : : bank);
785 : 21 : if (!avar || !avar->data_size)
786 : 3 : continue;
787 : :
788 : : /* Verify the signature. sha256 is 32 bytes long. */
789 : 18 : rc = verify_signature(auth, hash, 32, avar);
790 : :
791 : : /* Break if signature verification is successful */
792 : 18 : if (rc == OPAL_SUCCESS) {
793 : 8 : prlog(PR_INFO, "Key %s successfully verified by authority %s\n", update->key, key_authority[i]);
794 : 8 : break;
795 : : }
796 : : }
797 : :
798 : 6 : out:
799 : 32 : free(auth_buffer);
800 : 32 : free(hash);
801 : :
802 : 32 : return rc;
803 : : }
|