load_uefi.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kernel.h>
  3. #include <linux/sched.h>
  4. #include <linux/cred.h>
  5. #include <linux/dmi.h>
  6. #include <linux/err.h>
  7. #include <linux/efi.h>
  8. #include <linux/slab.h>
  9. #include <linux/ima.h>
  10. #include <keys/asymmetric-type.h>
  11. #include <keys/system_keyring.h>
  12. #include "../integrity.h"
  13. #include "keyring_handler.h"
  14. /*
  15. * On T2 Macs reading the db and dbx efi variables to load UEFI Secure Boot
  16. * certificates causes occurrence of a page fault in Apple's firmware and
  17. * a crash disabling EFI runtime services. The following quirk skips reading
  18. * these variables.
  19. */
  20. static const struct dmi_system_id uefi_skip_cert[] = {
  21. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,1") },
  22. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,2") },
  23. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,3") },
  24. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,4") },
  25. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,1") },
  26. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,2") },
  27. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,3") },
  28. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,4") },
  29. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") },
  30. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") },
  31. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") },
  32. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "Macmini8,1") },
  33. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
  34. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
  35. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
  36. { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") },
  37. { }
  38. };
  39. /*
  40. * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
  41. * it does.
  42. *
  43. * This UEFI variable is set by the shim if a user tells the shim to not use
  44. * the certs/hashes in the UEFI db variable for verification purposes. If it
  45. * is set, we should ignore the db variable also and the true return indicates
  46. * this.
  47. */
  48. static __init bool uefi_check_ignore_db(void)
  49. {
  50. efi_status_t status;
  51. unsigned int db = 0;
  52. unsigned long size = sizeof(db);
  53. efi_guid_t guid = EFI_SHIM_LOCK_GUID;
  54. status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
  55. return status == EFI_SUCCESS;
  56. }
  57. /*
  58. * Get a certificate list blob from the named EFI variable.
  59. */
  60. static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
  61. unsigned long *size, efi_status_t *status)
  62. {
  63. unsigned long lsize = 4;
  64. unsigned long tmpdb[4];
  65. void *db;
  66. *status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
  67. if (*status == EFI_NOT_FOUND)
  68. return NULL;
  69. if (*status != EFI_BUFFER_TOO_SMALL) {
  70. pr_err("Couldn't get size: 0x%lx\n", *status);
  71. return NULL;
  72. }
  73. db = kmalloc(lsize, GFP_KERNEL);
  74. if (!db)
  75. return NULL;
  76. *status = efi.get_variable(name, guid, NULL, &lsize, db);
  77. if (*status != EFI_SUCCESS) {
  78. kfree(db);
  79. pr_err("Error reading db var: 0x%lx\n", *status);
  80. return NULL;
  81. }
  82. *size = lsize;
  83. return db;
  84. }
  85. /*
  86. * load_moklist_certs() - Load MokList certs
  87. *
  88. * Load the certs contained in the UEFI MokListRT database into the
  89. * platform trusted keyring.
  90. *
  91. * This routine checks the EFI MOK config table first. If and only if
  92. * that fails, this routine uses the MokListRT ordinary UEFI variable.
  93. *
  94. * Return: Status
  95. */
  96. static int __init load_moklist_certs(void)
  97. {
  98. struct efi_mokvar_table_entry *mokvar_entry;
  99. efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
  100. void *mok;
  101. unsigned long moksize;
  102. efi_status_t status;
  103. int rc;
  104. /* First try to load certs from the EFI MOKvar config table.
  105. * It's not an error if the MOKvar config table doesn't exist
  106. * or the MokListRT entry is not found in it.
  107. */
  108. mokvar_entry = efi_mokvar_entry_find("MokListRT");
  109. if (mokvar_entry) {
  110. rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)",
  111. mokvar_entry->data,
  112. mokvar_entry->data_size,
  113. get_handler_for_mok);
  114. /* All done if that worked. */
  115. if (!rc)
  116. return rc;
  117. pr_err("Couldn't parse MokListRT signatures from EFI MOKvar config table: %d\n",
  118. rc);
  119. }
  120. /* Get MokListRT. It might not exist, so it isn't an error
  121. * if we can't get it.
  122. */
  123. mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status);
  124. if (mok) {
  125. rc = parse_efi_signature_list("UEFI:MokListRT",
  126. mok, moksize, get_handler_for_mok);
  127. kfree(mok);
  128. if (rc)
  129. pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
  130. return rc;
  131. }
  132. if (status == EFI_NOT_FOUND)
  133. pr_debug("MokListRT variable wasn't found\n");
  134. else
  135. pr_info("Couldn't get UEFI MokListRT\n");
  136. return 0;
  137. }
  138. /*
  139. * load_uefi_certs() - Load certs from UEFI sources
  140. *
  141. * Load the certs contained in the UEFI databases into the platform trusted
  142. * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
  143. * keyring.
  144. */
  145. static int __init load_uefi_certs(void)
  146. {
  147. efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
  148. efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
  149. void *db = NULL, *dbx = NULL, *mokx = NULL;
  150. unsigned long dbsize = 0, dbxsize = 0, mokxsize = 0;
  151. efi_status_t status;
  152. int rc = 0;
  153. const struct dmi_system_id *dmi_id;
  154. dmi_id = dmi_first_match(uefi_skip_cert);
  155. if (dmi_id) {
  156. pr_err("Reading UEFI Secure Boot Certs is not supported on T2 Macs.\n");
  157. return false;
  158. }
  159. if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
  160. return false;
  161. /* Get db and dbx. They might not exist, so it isn't an error
  162. * if we can't get them.
  163. */
  164. if (!uefi_check_ignore_db()) {
  165. db = get_cert_list(L"db", &secure_var, &dbsize, &status);
  166. if (!db) {
  167. if (status == EFI_NOT_FOUND)
  168. pr_debug("MODSIGN: db variable wasn't found\n");
  169. else
  170. pr_err("MODSIGN: Couldn't get UEFI db list\n");
  171. } else {
  172. rc = parse_efi_signature_list("UEFI:db",
  173. db, dbsize, get_handler_for_db);
  174. if (rc)
  175. pr_err("Couldn't parse db signatures: %d\n",
  176. rc);
  177. kfree(db);
  178. }
  179. }
  180. dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status);
  181. if (!dbx) {
  182. if (status == EFI_NOT_FOUND)
  183. pr_debug("dbx variable wasn't found\n");
  184. else
  185. pr_info("Couldn't get UEFI dbx list\n");
  186. } else {
  187. rc = parse_efi_signature_list("UEFI:dbx",
  188. dbx, dbxsize,
  189. get_handler_for_dbx);
  190. if (rc)
  191. pr_err("Couldn't parse dbx signatures: %d\n", rc);
  192. kfree(dbx);
  193. }
  194. /* the MOK/MOKx can not be trusted when secure boot is disabled */
  195. if (!arch_ima_get_secureboot())
  196. return 0;
  197. mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status);
  198. if (!mokx) {
  199. if (status == EFI_NOT_FOUND)
  200. pr_debug("mokx variable wasn't found\n");
  201. else
  202. pr_info("Couldn't get mokx list\n");
  203. } else {
  204. rc = parse_efi_signature_list("UEFI:MokListXRT",
  205. mokx, mokxsize,
  206. get_handler_for_dbx);
  207. if (rc)
  208. pr_err("Couldn't parse mokx signatures %d\n", rc);
  209. kfree(mokx);
  210. }
  211. /* Load the MokListRT certs */
  212. rc = load_moklist_certs();
  213. return rc;
  214. }
  215. late_initcall(load_uefi_certs);