integrity: Define a trusted platform keyring
On secure boot enabled systems, a verified kernel may need to kexec additional kernels. For example, it may be used as a bootloader needing to kexec a target kernel or it may need to kexec a crashdump kernel. In such cases, it may want to verify the signature of the next kernel image. It is further possible that the kernel image is signed with third party keys which are stored as platform or firmware keys in the 'db' variable. The kernel, however, can not directly verify these platform keys, and an administrator may therefore not want to trust them for arbitrary usage. In order to differentiate platform keys from other keys and provide the necessary separation of trust, the kernel needs an additional keyring to store platform keys. This patch creates the new keyring called ".platform" to isolate keys provided by platform from keys by kernel. These keys are used to facilitate signature verification during kexec. Since the scope of this keyring is only the platform/firmware keys, it cannot be updated from userspace. This keyring can be enabled by setting CONFIG_INTEGRITY_PLATFORM_KEYRING. Signed-off-by: Nayna Jain <nayna@linux.ibm.com> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> Acked-by: Serge Hallyn <serge@hallyn.com> Reviewed-by: James Morris <james.morris@microsoft.com> Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
parent
a802ed0dd9
commit
9dc92c4517
|
@ -51,6 +51,17 @@ config INTEGRITY_TRUSTED_KEYRING
|
||||||
.evm keyrings be signed by a key on the system trusted
|
.evm keyrings be signed by a key on the system trusted
|
||||||
keyring.
|
keyring.
|
||||||
|
|
||||||
|
config INTEGRITY_PLATFORM_KEYRING
|
||||||
|
bool "Provide keyring for platform/firmware trusted keys"
|
||||||
|
depends on INTEGRITY_ASYMMETRIC_KEYS
|
||||||
|
depends on SYSTEM_BLACKLIST_KEYRING
|
||||||
|
depends on EFI
|
||||||
|
help
|
||||||
|
Provide a separate, distinct keyring for platform trusted keys, which
|
||||||
|
the kernel automatically populates during initialization from values
|
||||||
|
provided by the platform for verifying the kexec'ed kerned image
|
||||||
|
and, possibly, the initramfs signature.
|
||||||
|
|
||||||
config INTEGRITY_AUDIT
|
config INTEGRITY_AUDIT
|
||||||
bool "Enables integrity auditing support "
|
bool "Enables integrity auditing support "
|
||||||
depends on AUDIT
|
depends on AUDIT
|
||||||
|
|
|
@ -9,6 +9,7 @@ integrity-y := iint.o
|
||||||
integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
|
integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
|
||||||
integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
|
integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
|
||||||
integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
|
integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
|
||||||
|
integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o
|
||||||
|
|
||||||
subdir-$(CONFIG_IMA) += ima
|
subdir-$(CONFIG_IMA) += ima
|
||||||
obj-$(CONFIG_IMA) += ima/
|
obj-$(CONFIG_IMA) += ima/
|
||||||
|
|
|
@ -35,6 +35,7 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
|
||||||
".ima",
|
".ima",
|
||||||
#endif
|
#endif
|
||||||
"_module",
|
"_module",
|
||||||
|
".platform",
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
|
#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
|
||||||
|
@ -73,12 +74,39 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init integrity_init_keyring(const unsigned int id)
|
static int __integrity_init_keyring(const unsigned int id, key_perm_t perm,
|
||||||
|
struct key_restriction *restriction)
|
||||||
{
|
{
|
||||||
const struct cred *cred = current_cred();
|
const struct cred *cred = current_cred();
|
||||||
struct key_restriction *restriction;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
|
||||||
|
KGIDT_INIT(0), cred, perm,
|
||||||
|
KEY_ALLOC_NOT_IN_QUOTA,
|
||||||
|
restriction, NULL);
|
||||||
|
if (IS_ERR(keyring[id])) {
|
||||||
|
err = PTR_ERR(keyring[id]);
|
||||||
|
pr_info("Can't allocate %s keyring (%d)\n",
|
||||||
|
keyring_name[id], err);
|
||||||
|
keyring[id] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init integrity_init_keyring(const unsigned int id)
|
||||||
|
{
|
||||||
|
struct key_restriction *restriction;
|
||||||
|
key_perm_t perm;
|
||||||
|
|
||||||
|
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
|
||||||
|
| KEY_USR_READ | KEY_USR_SEARCH;
|
||||||
|
|
||||||
|
if (id == INTEGRITY_KEYRING_PLATFORM) {
|
||||||
|
restriction = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
|
if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -87,21 +115,10 @@ int __init integrity_init_keyring(const unsigned int id)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
restriction->check = restrict_link_to_ima;
|
restriction->check = restrict_link_to_ima;
|
||||||
|
perm |= KEY_USR_WRITE;
|
||||||
|
|
||||||
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
|
out:
|
||||||
KGIDT_INIT(0), cred,
|
return __integrity_init_keyring(id, perm, restriction);
|
||||||
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
||||||
KEY_USR_VIEW | KEY_USR_READ |
|
|
||||||
KEY_USR_WRITE | KEY_USR_SEARCH),
|
|
||||||
KEY_ALLOC_NOT_IN_QUOTA,
|
|
||||||
restriction, NULL);
|
|
||||||
if (IS_ERR(keyring[id])) {
|
|
||||||
err = PTR_ERR(keyring[id]);
|
|
||||||
pr_info("Can't allocate %s keyring (%d)\n",
|
|
||||||
keyring_name[id], err);
|
|
||||||
keyring[id] = NULL;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init integrity_load_x509(const unsigned int id, const char *path)
|
int __init integrity_load_x509(const unsigned int id, const char *path)
|
||||||
|
|
|
@ -142,7 +142,8 @@ int integrity_kernel_read(struct file *file, loff_t offset,
|
||||||
#define INTEGRITY_KEYRING_EVM 0
|
#define INTEGRITY_KEYRING_EVM 0
|
||||||
#define INTEGRITY_KEYRING_IMA 1
|
#define INTEGRITY_KEYRING_IMA 1
|
||||||
#define INTEGRITY_KEYRING_MODULE 2
|
#define INTEGRITY_KEYRING_MODULE 2
|
||||||
#define INTEGRITY_KEYRING_MAX 3
|
#define INTEGRITY_KEYRING_PLATFORM 3
|
||||||
|
#define INTEGRITY_KEYRING_MAX 4
|
||||||
|
|
||||||
extern struct dentry *integrity_dir;
|
extern struct dentry *integrity_dir;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Platform keyring for firmware/platform keys
|
||||||
|
*
|
||||||
|
* Copyright IBM Corporation, 2018
|
||||||
|
* Author(s): Nayna Jain <nayna@linux.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/cred.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include "../integrity.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the trusted keyrings.
|
||||||
|
*/
|
||||||
|
static __init int platform_keyring_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = integrity_init_keyring(INTEGRITY_KEYRING_PLATFORM);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
pr_notice("Platform Keyring initialized\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be initialised before we try and load the keys into the keyring.
|
||||||
|
*/
|
||||||
|
device_initcall(platform_keyring_init);
|
Loading…
Reference in New Issue