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