1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2018 IBM Corporation
4 */
5#include <linux/efi.h>
6#include <linux/module.h>
7#include <linux/ima.h>
8#include <asm/efi.h>
9
10#ifndef arch_ima_efi_boot_mode
11#define arch_ima_efi_boot_mode efi_secureboot_mode_unset
12#endif
13
14static enum efi_secureboot_mode get_sb_mode(void)
15{
16	enum efi_secureboot_mode mode;
17
18	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {
19		pr_info("ima: secureboot mode unknown, no efi\n");
20		return efi_secureboot_mode_unknown;
21	}
22
23	mode = efi_get_secureboot_mode(efi.get_variable);
24	if (mode == efi_secureboot_mode_disabled)
25		pr_info("ima: secureboot mode disabled\n");
26	else if (mode == efi_secureboot_mode_unknown)
27		pr_info("ima: secureboot mode unknown\n");
28	else
29		pr_info("ima: secureboot mode enabled\n");
30	return mode;
31}
32
33bool arch_ima_get_secureboot(void)
34{
35	static enum efi_secureboot_mode sb_mode;
36	static bool initialized;
37
38	if (!initialized && efi_enabled(EFI_BOOT)) {
39		sb_mode = arch_ima_efi_boot_mode;
40
41		if (sb_mode == efi_secureboot_mode_unset)
42			sb_mode = get_sb_mode();
43		initialized = true;
44	}
45
46	if (sb_mode == efi_secureboot_mode_enabled)
47		return true;
48	else
49		return false;
50}
51
52/* secureboot arch rules */
53static const char * const sb_arch_rules[] = {
54#if !IS_ENABLED(CONFIG_KEXEC_SIG)
55	"appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig",
56#endif /* CONFIG_KEXEC_SIG */
57	"measure func=KEXEC_KERNEL_CHECK",
58#if !IS_ENABLED(CONFIG_MODULE_SIG)
59	"appraise func=MODULE_CHECK appraise_type=imasig",
60#endif
61#if IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING) && IS_ENABLED(CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY)
62	"appraise func=POLICY_CHECK appraise_type=imasig",
63#endif
64	"measure func=MODULE_CHECK",
65	NULL
66};
67
68const char * const *arch_get_ima_policy(void)
69{
70	if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) {
71		if (IS_ENABLED(CONFIG_MODULE_SIG))
72			set_module_sig_enforced();
73		if (IS_ENABLED(CONFIG_KEXEC_SIG))
74			set_kexec_sig_enforced();
75		return sb_arch_rules;
76	}
77	return NULL;
78}
79