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 <keys/asymmetric-type.h> 10 #include <keys/system_keyring.h> 11 #include "../integrity.h" 12 #include "keyring_handler.h" 13 14 static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID; 15 static efi_guid_t efi_cert_x509_sha256_guid __initdata = 16 EFI_CERT_X509_SHA256_GUID; 17 static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; 18 19 /* 20 * Look to see if a UEFI variable called MokIgnoreDB exists and return true if 21 * it does. 22 * 23 * This UEFI variable is set by the shim if a user tells the shim to not use 24 * the certs/hashes in the UEFI db variable for verification purposes. If it 25 * is set, we should ignore the db variable also and the true return indicates 26 * this. 27 */ 28 static __init bool uefi_check_ignore_db(void) 29 { 30 efi_status_t status; 31 unsigned int db = 0; 32 unsigned long size = sizeof(db); 33 efi_guid_t guid = EFI_SHIM_LOCK_GUID; 34 35 status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db); 36 return status == EFI_SUCCESS; 37 } 38 39 /* 40 * Get a certificate list blob from the named EFI variable. 41 */ 42 static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, 43 unsigned long *size) 44 { 45 efi_status_t status; 46 unsigned long lsize = 4; 47 unsigned long tmpdb[4]; 48 void *db; 49 50 status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); 51 if (status != EFI_BUFFER_TOO_SMALL) { 52 pr_err("Couldn't get size: 0x%lx\n", status); 53 return NULL; 54 } 55 56 db = kmalloc(lsize, GFP_KERNEL); 57 if (!db) 58 return NULL; 59 60 status = efi.get_variable(name, guid, NULL, &lsize, db); 61 if (status != EFI_SUCCESS) { 62 kfree(db); 63 pr_err("Error reading db var: 0x%lx\n", status); 64 return NULL; 65 } 66 67 *size = lsize; 68 return db; 69 } 70 71 /* 72 * Load the certs contained in the UEFI databases into the platform trusted 73 * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist 74 * keyring. 75 */ 76 static int __init load_uefi_certs(void) 77 { 78 efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; 79 efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; 80 void *db = NULL, *dbx = NULL, *mok = NULL; 81 unsigned long dbsize = 0, dbxsize = 0, moksize = 0; 82 int rc = 0; 83 84 if (!efi.get_variable) 85 return false; 86 87 /* Get db, MokListRT, and dbx. They might not exist, so it isn't 88 * an error if we can't get them. 89 */ 90 if (!uefi_check_ignore_db()) { 91 db = get_cert_list(L"db", &secure_var, &dbsize); 92 if (!db) { 93 pr_err("MODSIGN: Couldn't get UEFI db list\n"); 94 } else { 95 rc = parse_efi_signature_list("UEFI:db", 96 db, dbsize, get_handler_for_db); 97 if (rc) 98 pr_err("Couldn't parse db signatures: %d\n", 99 rc); 100 kfree(db); 101 } 102 } 103 104 mok = get_cert_list(L"MokListRT", &mok_var, &moksize); 105 if (!mok) { 106 pr_info("Couldn't get UEFI MokListRT\n"); 107 } else { 108 rc = parse_efi_signature_list("UEFI:MokListRT", 109 mok, moksize, get_handler_for_db); 110 if (rc) 111 pr_err("Couldn't parse MokListRT signatures: %d\n", rc); 112 kfree(mok); 113 } 114 115 dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); 116 if (!dbx) { 117 pr_info("Couldn't get UEFI dbx list\n"); 118 } else { 119 rc = parse_efi_signature_list("UEFI:dbx", 120 dbx, dbxsize, 121 get_handler_for_dbx); 122 if (rc) 123 pr_err("Couldn't parse dbx signatures: %d\n", rc); 124 kfree(dbx); 125 } 126 127 return rc; 128 } 129 late_initcall(load_uefi_certs); 130