0001
0002
0003 #include <linux/kernel.h>
0004 #include <linux/sched.h>
0005 #include <linux/cred.h>
0006 #include <linux/dmi.h>
0007 #include <linux/err.h>
0008 #include <linux/efi.h>
0009 #include <linux/slab.h>
0010 #include <linux/ima.h>
0011 #include <keys/asymmetric-type.h>
0012 #include <keys/system_keyring.h>
0013 #include "../integrity.h"
0014 #include "keyring_handler.h"
0015
0016
0017
0018
0019
0020
0021
0022 static const struct dmi_system_id uefi_skip_cert[] = {
0023 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,1") },
0024 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,2") },
0025 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,3") },
0026 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,4") },
0027 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,1") },
0028 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,2") },
0029 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,3") },
0030 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,4") },
0031 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") },
0032 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") },
0033 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") },
0034 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacMini8,1") },
0035 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
0036 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
0037 { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
0038 { }
0039 };
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 static __init bool uefi_check_ignore_db(void)
0051 {
0052 efi_status_t status;
0053 unsigned int db = 0;
0054 unsigned long size = sizeof(db);
0055 efi_guid_t guid = EFI_SHIM_LOCK_GUID;
0056
0057 status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
0058 return status == EFI_SUCCESS;
0059 }
0060
0061
0062
0063
0064 static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
0065 unsigned long *size, efi_status_t *status)
0066 {
0067 unsigned long lsize = 4;
0068 unsigned long tmpdb[4];
0069 void *db;
0070
0071 *status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
0072 if (*status == EFI_NOT_FOUND)
0073 return NULL;
0074
0075 if (*status != EFI_BUFFER_TOO_SMALL) {
0076 pr_err("Couldn't get size: 0x%lx\n", *status);
0077 return NULL;
0078 }
0079
0080 db = kmalloc(lsize, GFP_KERNEL);
0081 if (!db)
0082 return NULL;
0083
0084 *status = efi.get_variable(name, guid, NULL, &lsize, db);
0085 if (*status != EFI_SUCCESS) {
0086 kfree(db);
0087 pr_err("Error reading db var: 0x%lx\n", *status);
0088 return NULL;
0089 }
0090
0091 *size = lsize;
0092 return db;
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 static int __init load_moklist_certs(void)
0107 {
0108 struct efi_mokvar_table_entry *mokvar_entry;
0109 efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
0110 void *mok;
0111 unsigned long moksize;
0112 efi_status_t status;
0113 int rc;
0114
0115
0116
0117
0118
0119 mokvar_entry = efi_mokvar_entry_find("MokListRT");
0120 if (mokvar_entry) {
0121 rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)",
0122 mokvar_entry->data,
0123 mokvar_entry->data_size,
0124 get_handler_for_mok);
0125
0126 if (!rc)
0127 return rc;
0128
0129 pr_err("Couldn't parse MokListRT signatures from EFI MOKvar config table: %d\n",
0130 rc);
0131 }
0132
0133
0134
0135
0136 mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status);
0137 if (mok) {
0138 rc = parse_efi_signature_list("UEFI:MokListRT",
0139 mok, moksize, get_handler_for_mok);
0140 kfree(mok);
0141 if (rc)
0142 pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
0143 return rc;
0144 }
0145 if (status == EFI_NOT_FOUND)
0146 pr_debug("MokListRT variable wasn't found\n");
0147 else
0148 pr_info("Couldn't get UEFI MokListRT\n");
0149 return 0;
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159 static int __init load_uefi_certs(void)
0160 {
0161 efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
0162 efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
0163 void *db = NULL, *dbx = NULL, *mokx = NULL;
0164 unsigned long dbsize = 0, dbxsize = 0, mokxsize = 0;
0165 efi_status_t status;
0166 int rc = 0;
0167 const struct dmi_system_id *dmi_id;
0168
0169 dmi_id = dmi_first_match(uefi_skip_cert);
0170 if (dmi_id) {
0171 pr_err("Reading UEFI Secure Boot Certs is not supported on T2 Macs.\n");
0172 return false;
0173 }
0174
0175 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
0176 return false;
0177
0178
0179
0180
0181 if (!uefi_check_ignore_db()) {
0182 db = get_cert_list(L"db", &secure_var, &dbsize, &status);
0183 if (!db) {
0184 if (status == EFI_NOT_FOUND)
0185 pr_debug("MODSIGN: db variable wasn't found\n");
0186 else
0187 pr_err("MODSIGN: Couldn't get UEFI db list\n");
0188 } else {
0189 rc = parse_efi_signature_list("UEFI:db",
0190 db, dbsize, get_handler_for_db);
0191 if (rc)
0192 pr_err("Couldn't parse db signatures: %d\n",
0193 rc);
0194 kfree(db);
0195 }
0196 }
0197
0198 dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status);
0199 if (!dbx) {
0200 if (status == EFI_NOT_FOUND)
0201 pr_debug("dbx variable wasn't found\n");
0202 else
0203 pr_info("Couldn't get UEFI dbx list\n");
0204 } else {
0205 rc = parse_efi_signature_list("UEFI:dbx",
0206 dbx, dbxsize,
0207 get_handler_for_dbx);
0208 if (rc)
0209 pr_err("Couldn't parse dbx signatures: %d\n", rc);
0210 kfree(dbx);
0211 }
0212
0213
0214 if (!arch_ima_get_secureboot())
0215 return 0;
0216
0217 mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status);
0218 if (!mokx) {
0219 if (status == EFI_NOT_FOUND)
0220 pr_debug("mokx variable wasn't found\n");
0221 else
0222 pr_info("Couldn't get mokx list\n");
0223 } else {
0224 rc = parse_efi_signature_list("UEFI:MokListXRT",
0225 mokx, mokxsize,
0226 get_handler_for_dbx);
0227 if (rc)
0228 pr_err("Couldn't parse mokx signatures %d\n", rc);
0229 kfree(mokx);
0230 }
0231
0232
0233 rc = load_moklist_certs();
0234
0235 return rc;
0236 }
0237 late_initcall(load_uefi_certs);