Commit 60c8eb38 authored by Mimi Zohar's avatar Mimi Zohar
Browse files

Merge branch 'ima-module-signing-v4' into next-integrity

From the series cover letter:

Kernel modules are currently only signed when CONFIG_MODULE_SIG is enabled.
The kernel module signing key is a self-signed CA only loaded onto the
.builtin_trusted_key keyring.  On secure boot enabled systems with an arch
specific IMA policy enabled, but without MODULE_SIG enabled, kernel modules
are not signed, nor is the kernel module signing public key loaded onto the
IMA keyring.

In order to load the the kernel module signing key onto the IMA trusted
keyring ('.ima'), the certificate needs to be signed by a CA key either on
the builtin or secondary keyrings. The original version of this patch set
created and loaded a kernel-CA key onto the builtin keyring. The kernel-CA
key signed the kernel module signing key, allowing it to be loaded onto the
IMA trusted keyring.

However, missing from this version was support for the kernel-CA to sign the
hardware token certificate. Adding that support would add additional
complexity.

Since the kernel module signing key is embedded into the Linux kernel at
build time, instead of creating and loading a kernel-CA onto the builtin
trusted keyring, this version makes an exception and allows the
self-signed kernel module signing key to be loaded directly onto the
trusted IMA keyring.
parents 7990ccaf 6cbdfb3d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1523,9 +1523,9 @@ MRPROPER_FILES += include/config include/generated \
		  debian snap tar-install \
		  .config .config.old .version \
		  Module.symvers \
		  signing_key.pem signing_key.priv signing_key.x509	\
		  x509.genkey extra_certificates signing_key.x509.keyid	\
		  signing_key.x509.signer vmlinux-gdb.py \
		  certs/signing_key.pem certs/signing_key.x509 \
		  certs/x509.genkey \
		  vmlinux-gdb.py \
		  *.spec

# Directories & files removed with 'make distclean'
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ menu "Certificates for signature checking"
config MODULE_SIG_KEY
	string "File name or PKCS#11 URI of module signing key"
	default "certs/signing_key.pem"
	depends on MODULE_SIG
	depends on MODULE_SIG || IMA_APPRAISE_MODSIG
	help
         Provide the file name of a private key/certificate in PEM format,
         or a PKCS#11 URI according to RFC7512. The file should contain, or
+8 −0
Original line number Diff line number Diff line
@@ -32,6 +32,14 @@ endif # CONFIG_SYSTEM_TRUSTED_KEYRING
clean-files := x509_certificate_list .x509.list

ifeq ($(CONFIG_MODULE_SIG),y)
	SIGN_KEY = y
endif

ifeq ($(CONFIG_IMA_APPRAISE_MODSIG),y)
	SIGN_KEY = y
endif

ifdef SIGN_KEY
###############################################################################
#
# If module signing is requested, say by allyesconfig, but a key has not been
+12 −1
Original line number Diff line number Diff line
@@ -8,9 +8,11 @@
	.globl system_certificate_list
system_certificate_list:
__cert_list_start:
#ifdef CONFIG_MODULE_SIG
__module_cert_start:
#if defined(CONFIG_MODULE_SIG) || defined(CONFIG_IMA_APPRAISE_MODSIG)
	.incbin "certs/signing_key.x509"
#endif
__module_cert_end:
	.incbin "certs/x509_certificate_list"
__cert_list_end:

@@ -35,3 +37,12 @@ system_certificate_list_size:
#else
	.long __cert_list_end - __cert_list_start
#endif

	.align 8
	.globl module_cert_size
module_cert_size:
#ifdef CONFIG_64BIT
	.quad __module_cert_end - __module_cert_start
#else
	.long __module_cert_end - __module_cert_start
#endif
+40 −10
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ static struct key *platform_trusted_keys;

extern __initconst const u8 system_certificate_list[];
extern __initconst const unsigned long system_certificate_list_size;
extern __initconst const unsigned long module_cert_size;

/**
 * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
@@ -132,19 +133,11 @@ static __init int system_trusted_keyring_init(void)
 */
device_initcall(system_trusted_keyring_init);

/*
 * Load the compiled-in list of X.509 certificates.
 */
static __init int load_system_certificate_list(void)
static __init int load_cert(const u8 *p, const u8 *end, struct key *keyring)
{
	key_ref_t key;
	const u8 *p, *end;
	size_t plen;

	pr_notice("Loading compiled-in X.509 certificates\n");

	p = system_certificate_list;
	end = p + system_certificate_list_size;
	while (p < end) {
		/* Each cert begins with an ASN.1 SEQUENCE tag and must be more
		 * than 256 bytes in size.
@@ -159,7 +152,7 @@ static __init int load_system_certificate_list(void)
		if (plen > end - p)
			goto dodgy_cert;

		key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1),
		key = key_create_or_update(make_key_ref(keyring, 1),
					   "asymmetric",
					   NULL,
					   p,
@@ -186,6 +179,43 @@ static __init int load_system_certificate_list(void)
	pr_err("Problem parsing in-kernel X.509 certificate list\n");
	return 0;
}

__init int load_module_cert(struct key *keyring)
{
	const u8 *p, *end;

	if (!IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG))
		return 0;

	pr_notice("Loading compiled-in module X.509 certificates\n");

	p = system_certificate_list;
	end = p + module_cert_size;

	return load_cert(p, end, keyring);
}

/*
 * Load the compiled-in list of X.509 certificates.
 */
static __init int load_system_certificate_list(void)
{
	const u8 *p, *end;
	unsigned long size;

	pr_notice("Loading compiled-in X.509 certificates\n");

#ifdef CONFIG_MODULE_SIG
	p = system_certificate_list;
	size = system_certificate_list_size;
#else
	p = system_certificate_list + module_cert_size;
	size = system_certificate_list_size - module_cert_size;
#endif

	end = p + size;
	return load_cert(p, end, builtin_trusted_keys);
}
late_initcall(load_system_certificate_list);

#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
Loading