18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Secure boot handling.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2013,2014 Linaro Limited
68c2ecf20Sopenharmony_ci *     Roy Franz <roy.franz@linaro.org
78c2ecf20Sopenharmony_ci * Copyright (C) 2013 Red Hat, Inc.
88c2ecf20Sopenharmony_ci *     Mark Salter <msalter@redhat.com>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci#include <linux/efi.h>
118c2ecf20Sopenharmony_ci#include <asm/efi.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "efistub.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/* BIOS variables */
168c2ecf20Sopenharmony_cistatic const efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
178c2ecf20Sopenharmony_cistatic const efi_char16_t efi_SecureBoot_name[] = L"SecureBoot";
188c2ecf20Sopenharmony_cistatic const efi_char16_t efi_SetupMode_name[] = L"SetupMode";
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/* SHIM variables */
218c2ecf20Sopenharmony_cistatic const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
228c2ecf20Sopenharmony_cistatic const efi_char16_t shim_MokSBState_name[] = L"MokSBStateRT";
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci * Determine whether we're in secure boot mode.
268c2ecf20Sopenharmony_ci *
278c2ecf20Sopenharmony_ci * Please keep the logic in sync with
288c2ecf20Sopenharmony_ci * arch/x86/xen/efi.c:xen_efi_get_secureboot().
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_cienum efi_secureboot_mode efi_get_secureboot(void)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	u32 attr;
338c2ecf20Sopenharmony_ci	u8 secboot, setupmode, moksbstate;
348c2ecf20Sopenharmony_ci	unsigned long size;
358c2ecf20Sopenharmony_ci	efi_status_t status;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	size = sizeof(secboot);
388c2ecf20Sopenharmony_ci	status = get_efi_var(efi_SecureBoot_name, &efi_variable_guid,
398c2ecf20Sopenharmony_ci			     NULL, &size, &secboot);
408c2ecf20Sopenharmony_ci	if (status == EFI_NOT_FOUND)
418c2ecf20Sopenharmony_ci		return efi_secureboot_mode_disabled;
428c2ecf20Sopenharmony_ci	if (status != EFI_SUCCESS)
438c2ecf20Sopenharmony_ci		goto out_efi_err;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	size = sizeof(setupmode);
468c2ecf20Sopenharmony_ci	status = get_efi_var(efi_SetupMode_name, &efi_variable_guid,
478c2ecf20Sopenharmony_ci			     NULL, &size, &setupmode);
488c2ecf20Sopenharmony_ci	if (status != EFI_SUCCESS)
498c2ecf20Sopenharmony_ci		goto out_efi_err;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	if (secboot == 0 || setupmode == 1)
528c2ecf20Sopenharmony_ci		return efi_secureboot_mode_disabled;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	/*
558c2ecf20Sopenharmony_ci	 * See if a user has put the shim into insecure mode. If so, and if the
568c2ecf20Sopenharmony_ci	 * variable doesn't have the non-volatile attribute set, we might as
578c2ecf20Sopenharmony_ci	 * well honor that.
588c2ecf20Sopenharmony_ci	 */
598c2ecf20Sopenharmony_ci	size = sizeof(moksbstate);
608c2ecf20Sopenharmony_ci	status = get_efi_var(shim_MokSBState_name, &shim_guid,
618c2ecf20Sopenharmony_ci			     &attr, &size, &moksbstate);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/* If it fails, we don't care why. Default to secure */
648c2ecf20Sopenharmony_ci	if (status != EFI_SUCCESS)
658c2ecf20Sopenharmony_ci		goto secure_boot_enabled;
668c2ecf20Sopenharmony_ci	if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1)
678c2ecf20Sopenharmony_ci		return efi_secureboot_mode_disabled;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cisecure_boot_enabled:
708c2ecf20Sopenharmony_ci	efi_info("UEFI Secure Boot is enabled.\n");
718c2ecf20Sopenharmony_ci	return efi_secureboot_mode_enabled;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciout_efi_err:
748c2ecf20Sopenharmony_ci	efi_err("Could not determine UEFI Secure Boot status.\n");
758c2ecf20Sopenharmony_ci	return efi_secureboot_mode_unknown;
768c2ecf20Sopenharmony_ci}
77