1de8cb458SDavid Howells /* 2de8cb458SDavid Howells * Secure boot handling. 3de8cb458SDavid Howells * 4de8cb458SDavid Howells * Copyright (C) 2013,2014 Linaro Limited 5de8cb458SDavid Howells * Roy Franz <roy.franz@linaro.org 6de8cb458SDavid Howells * Copyright (C) 2013 Red Hat, Inc. 7de8cb458SDavid Howells * Mark Salter <msalter@redhat.com> 8de8cb458SDavid Howells * 9de8cb458SDavid Howells * This file is part of the Linux kernel, and is made available under the 10de8cb458SDavid Howells * terms of the GNU General Public License version 2. 11de8cb458SDavid Howells */ 12de8cb458SDavid Howells #include <linux/efi.h> 13de8cb458SDavid Howells #include <asm/efi.h> 14de8cb458SDavid Howells 15*eeff7d63SArd Biesheuvel #include "efistub.h" 16*eeff7d63SArd Biesheuvel 17de8cb458SDavid Howells /* BIOS variables */ 18de8cb458SDavid Howells static const efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; 19de8cb458SDavid Howells static const efi_char16_t const efi_SecureBoot_name[] = { 20de8cb458SDavid Howells 'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 21de8cb458SDavid Howells }; 22de8cb458SDavid Howells static const efi_char16_t const efi_SetupMode_name[] = { 23de8cb458SDavid Howells 'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 24de8cb458SDavid Howells }; 25de8cb458SDavid Howells 26f3cf6f74SJosh Boyer /* SHIM variables */ 27f3cf6f74SJosh Boyer static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; 28f3cf6f74SJosh Boyer static efi_char16_t const shim_MokSBState_name[] = { 29f3cf6f74SJosh Boyer 'M', 'o', 'k', 'S', 'B', 'S', 't', 'a', 't', 'e', 0 30f3cf6f74SJosh Boyer }; 31f3cf6f74SJosh Boyer 32de8cb458SDavid Howells #define get_efi_var(name, vendor, ...) \ 33de8cb458SDavid Howells efi_call_runtime(get_variable, \ 34de8cb458SDavid Howells (efi_char16_t *)(name), (efi_guid_t *)(vendor), \ 35de8cb458SDavid Howells __VA_ARGS__); 36de8cb458SDavid Howells 37de8cb458SDavid Howells /* 38de8cb458SDavid Howells * Determine whether we're in secure boot mode. 39de8cb458SDavid Howells */ 40de8cb458SDavid Howells enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg) 41de8cb458SDavid Howells { 42f3cf6f74SJosh Boyer u32 attr; 43f3cf6f74SJosh Boyer u8 secboot, setupmode, moksbstate; 44de8cb458SDavid Howells unsigned long size; 45de8cb458SDavid Howells efi_status_t status; 46de8cb458SDavid Howells 47de8cb458SDavid Howells size = sizeof(secboot); 48de8cb458SDavid Howells status = get_efi_var(efi_SecureBoot_name, &efi_variable_guid, 49de8cb458SDavid Howells NULL, &size, &secboot); 5052e51f16SArd Biesheuvel if (status == EFI_NOT_FOUND) 5152e51f16SArd Biesheuvel return efi_secureboot_mode_disabled; 52de8cb458SDavid Howells if (status != EFI_SUCCESS) 53de8cb458SDavid Howells goto out_efi_err; 54de8cb458SDavid Howells 55de8cb458SDavid Howells size = sizeof(setupmode); 56de8cb458SDavid Howells status = get_efi_var(efi_SetupMode_name, &efi_variable_guid, 57de8cb458SDavid Howells NULL, &size, &setupmode); 58de8cb458SDavid Howells if (status != EFI_SUCCESS) 59de8cb458SDavid Howells goto out_efi_err; 60de8cb458SDavid Howells 61de8cb458SDavid Howells if (secboot == 0 || setupmode == 1) 62de8cb458SDavid Howells return efi_secureboot_mode_disabled; 63de8cb458SDavid Howells 64f3cf6f74SJosh Boyer /* 65f3cf6f74SJosh Boyer * See if a user has put the shim into insecure mode. If so, and if the 66f3cf6f74SJosh Boyer * variable doesn't have the runtime attribute set, we might as well 67f3cf6f74SJosh Boyer * honor that. 68f3cf6f74SJosh Boyer */ 69f3cf6f74SJosh Boyer size = sizeof(moksbstate); 70f3cf6f74SJosh Boyer status = get_efi_var(shim_MokSBState_name, &shim_guid, 71f3cf6f74SJosh Boyer &attr, &size, &moksbstate); 72f3cf6f74SJosh Boyer 73f3cf6f74SJosh Boyer /* If it fails, we don't care why. Default to secure */ 74f3cf6f74SJosh Boyer if (status != EFI_SUCCESS) 75f3cf6f74SJosh Boyer goto secure_boot_enabled; 76f3cf6f74SJosh Boyer if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) && moksbstate == 1) 77f3cf6f74SJosh Boyer return efi_secureboot_mode_disabled; 78f3cf6f74SJosh Boyer 79f3cf6f74SJosh Boyer secure_boot_enabled: 80de8cb458SDavid Howells pr_efi(sys_table_arg, "UEFI Secure Boot is enabled.\n"); 81de8cb458SDavid Howells return efi_secureboot_mode_enabled; 82de8cb458SDavid Howells 83de8cb458SDavid Howells out_efi_err: 84de8cb458SDavid Howells pr_efi_err(sys_table_arg, "Could not determine UEFI Secure Boot status.\n"); 85de8cb458SDavid Howells return efi_secureboot_mode_unknown; 86de8cb458SDavid Howells } 87