From: Mimi Zohar <zohar@linux.vnet.ibm.com>
To: Takashi Iwai <tiwai@suse.de>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>,
Alan Cox <alan@lxorguk.ukuu.org.uk>, joeyli <jlee@suse.com>,
Jiri Kosina <jkosina@suse.cz>,
David Howells <dhowells@redhat.com>,
Rusty Russell <rusty@rustcorp.com.au>,
linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org, linux-efi@vger.ke
Subject: Re: [PATCH RFC 3/4] firmware: Add a signature check
Date: Tue, 06 Nov 2012 01:03:04 -0500 [thread overview]
Message-ID: <1352181784.8752.27.camel@falcor> (raw)
In-Reply-To: <s5hd2zs9db6.wl%tiwai@suse.de>
On Mon, 2012-11-05 at 18:20 +0100, Takashi Iwai wrote:
> Add a feature to check the firmware signature, specified via Kconfig
> CONFIG_FIRMWARE_SIG. The signature check is performed only for the
> direct fw loading without udev. Also no check for built-in firmware
> blobs is implemented yet.
>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> ---
> drivers/base/Kconfig | 6 +++++
> drivers/base/firmware_class.c | 56 +++++++++++++++++++++++++++++++++++---
> include/linux/firmware.h | 7 +++++
> kernel/module_signing.c | 63 +++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 128 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
> index b34b5cd..3696fd7 100644
> --- a/drivers/base/Kconfig
> +++ b/drivers/base/Kconfig
> @@ -145,6 +145,12 @@ config EXTRA_FIRMWARE_DIR
> this option you can point it elsewhere, such as /lib/firmware/ or
> some other directory containing the firmware files.
>
> +config FIRMWARE_SIG
> + bool "Firmware signature verification"
> + depends on FW_LOADER && MODULE_SIG
> + help
> + Enable firmware signature check.
> +
> config DEBUG_DRIVER
> bool "Driver Core verbose debug messages"
> depends on DEBUG_KERNEL
> diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
> index 8945f4e..575bc4c 100644
> --- a/drivers/base/firmware_class.c
> +++ b/drivers/base/firmware_class.c
> @@ -36,6 +36,11 @@ MODULE_AUTHOR("Manuel Estrada Sainz");
> MODULE_DESCRIPTION("Multi purpose firmware loading support");
> MODULE_LICENSE("GPL");
>
> +#ifdef CONFIG_FIRMWARE_SIG
> +static bool sig_enforce;
> +module_param(sig_enforce, bool, 0644);
> +#endif
> +
> /* Builtin firmware support */
>
> #ifdef CONFIG_FW_LOADER
> @@ -287,7 +292,7 @@ static noinline long fw_file_size(struct file *file)
> return st.size;
> }
>
> -static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
> +static bool fw_read_file_contents(struct file *file, void **bufp, size_t *sizep)
> {
> long size;
> char *buf;
> @@ -302,11 +307,39 @@ static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf
> vfree(buf);
> return false;
> }
> - fw_buf->data = buf;
> - fw_buf->size = size;
> + *bufp = buf;
> + *sizep = size;
> return true;
> }
>
> +#ifdef CONFIG_FIRMWARE_SIG
> +static bool verify_signature(struct firmware_buf *buf, const char *path)
> +{
> + const unsigned long markerlen = sizeof(FIRMWARE_SIG_STRING) - 1;
> + struct file *file;
> + void *sig_data;
> + size_t sig_size;
> + bool success;
> +
> + file = filp_open(path, O_RDONLY, 0);
> + if (IS_ERR(file))
> + return false;
> +
> + success = fw_read_file_contents(file, &sig_data, &sig_size);
> + fput(file);
> + if (success) {
> + if (sig_size > markerlen &&
> + !memcmp(sig_data, FIRMWARE_SIG_STRING, markerlen))
> + success = !fw_verify_sig(buf->data, buf->size,
> + sig_data + markerlen,
> + sig_size - markerlen);
> + pr_debug("verified signature %s: %d\n", path, success);
> + vfree(sig_data);
> + }
> + return success;
> +}
> +#endif /* CONFIG_FIRMWARE_SIG */
> +
> static bool fw_get_filesystem_firmware(struct firmware_buf *buf)
> {
> int i;
> @@ -320,8 +353,23 @@ static bool fw_get_filesystem_firmware(struct firmware_buf *buf)
> file = filp_open(path, O_RDONLY, 0);
> if (IS_ERR(file))
> continue;
> - success = fw_read_file_contents(file, buf);
> + success = fw_read_file_contents(file, &buf->data, &buf->size);
> fput(file);
> +#ifdef CONFIG_FIRMWARE_SIG
> + if (success) {
> + snprintf(path, PATH_MAX, "%s/%s.sig", fw_path[i],
> + buf->fw_id);
> + if (!verify_signature(buf, path)) {
> + pr_err("Invalid signature file %s\n", path);
> + if (sig_enforce) {
> + vfree(buf->data);
> + buf->data = NULL;
> + buf->size = 0;
> + success = false;
> + }
> + }
> + }
> +#endif /* CONFIG_FIRMWARE_SIG */
The existing kernel modules are read by userspace into a buffer, which
is passed to the kernel. As there is no way of verifying what was read
by userspace is the same as what was passed to the kernel, the signature
verification is done, in the kernel, on the buffer contents. The new
kernel module syscall passes a file descriptor. With commit "41110a4
ima: support new kernel module syscall" the kernel module signature is
measured/appraised like any other file in the IMA policy.
Although the default policy should already be measuring/appraising the
firmware, because of the open, you might want to add a new hook
FIRMWARE_CHECK here, for finer grain IMA policy control.
thanks,
Mimi
> if (success)
> break;
> }
> diff --git a/include/linux/firmware.h b/include/linux/firmware.h
> index e4279fe..2e9e457 100644
> --- a/include/linux/firmware.h
> +++ b/include/linux/firmware.h
> @@ -79,4 +79,11 @@ static inline int uncache_firmware(const char *name)
> }
> #endif
>
> +#ifdef CONFIG_FIRMWARE_SIG
> +#define FIRMWARE_SIG_STRING "~Linux firmware signature~\n"
> +/* defined in kernel/module_signing.c */
> +int fw_verify_sig(const void *fw_data, size_t fw_size,
> + const void *sig_data, size_t sig_size);
> +#endif
> +
> #endif
> diff --git a/kernel/module_signing.c b/kernel/module_signing.c
> index ea1b1df..7994452 100644
> --- a/kernel/module_signing.c
> +++ b/kernel/module_signing.c
> @@ -11,6 +11,7 @@
>
> #include <linux/kernel.h>
> #include <linux/err.h>
> +#include <linux/export.h>
> #include <crypto/public_key.h>
> #include <crypto/hash.h>
> #include <keys/asymmetric-type.h>
> @@ -247,3 +248,65 @@ error_put_key:
> pr_devel("<==%s() = %d\n", __func__, ret);
> return ret;
> }
> +
> +#ifdef CONFIG_FIRMWARE_SIG
> +/*
> + * Verify the firmware signature, similar like module signature check
> + * but it's stored in a separate file
> + */
> +int fw_verify_sig(const void *fw_data, size_t fw_size,
> + const void *sig_data, size_t sig_size)
> +{
> + struct public_key_signature *pks;
> + struct module_signature ms;
> + struct key *key;
> + size_t sig_len;
> + int ret;
> +
> + if (sig_size <= sizeof(ms))
> + return -EBADMSG;
> +
> + memcpy(&ms, sig_data, sizeof(ms));
> + sig_data += sizeof(ms);
> + sig_size -= sizeof(ms);
> +
> + sig_len = be32_to_cpu(ms.sig_len);
> + if (sig_size < sig_len + (size_t)ms.signer_len + ms.key_id_len)
> + return -EBADMSG;
> +
> + /* For the moment, only support RSA and X.509 identifiers */
> + if (ms.algo != PKEY_ALGO_RSA ||
> + ms.id_type != PKEY_ID_X509)
> + return -ENOPKG;
> +
> + if (ms.hash >= PKEY_HASH__LAST ||
> + !pkey_hash_algo[ms.hash])
> + return -ENOPKG;
> +
> + key = request_asymmetric_key(sig_data, ms.signer_len,
> + sig_data + ms.signer_len, ms.key_id_len);
> + if (IS_ERR(key))
> + return PTR_ERR(key);
> +
> + pks = mod_make_digest(ms.hash, fw_data, fw_size);
> + if (IS_ERR(pks)) {
> + ret = PTR_ERR(pks);
> + goto error_put_key;
> + }
> +
> + sig_data += ms.signer_len + ms.key_id_len;
> + ret = mod_extract_mpi_array(pks, sig_data, sig_len);
> + if (ret < 0)
> + goto error_free_pks;
> +
> + ret = verify_signature(key, pks);
> +
> +error_free_pks:
> + mpi_free(pks->rsa.s);
> + kfree(pks);
> +error_put_key:
> + key_put(key);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(fw_verify_sig);
> +#endif /* CONFIG_FIRMWARE_SIG */
next prev parent reply other threads:[~2012-11-06 5:06 UTC|newest]
Thread overview: 224+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-20 14:40 [RFC] Second attempt at kernel secure boot support Matthew Garrett
2012-09-20 14:40 ` [PATCH V2 01/10] Secure boot: Add new capability Matthew Garrett
2012-09-28 3:10 ` Serge Hallyn
2012-10-20 0:15 ` joeyli
2012-10-20 9:02 ` Matt Fleming
2012-09-20 14:40 ` [PATCH V2 02/10] PCI: Lock down BAR access in secure boot environments Matthew Garrett
2012-09-20 14:40 ` [PATCH V2 03/10] x86: Lock down IO port " Matthew Garrett
2012-09-20 14:40 ` [PATCH V2 04/10] ACPI: Limit access to custom_method Matthew Garrett
2012-09-20 14:41 ` [PATCH V2 05/10] asus-wmi: Restrict debugfs interface Matthew Garrett
2012-09-20 14:41 ` [PATCH V2 06/10] Restrict /dev/mem and /dev/kmem in secure boot setups Matthew Garrett
2012-09-20 14:41 ` [PATCH V2 07/10] Secure boot: Add a dummy kernel parameter that will switch on Secure Boot mode Matthew Garrett
2012-09-20 16:32 ` Greg KH
2012-09-20 17:40 ` Josh Boyer
2012-09-25 13:08 ` [PATCH V3 " Josh Boyer
2012-10-29 9:00 ` joeyli
2012-10-30 17:48 ` Josh Boyer
2012-10-30 19:27 ` joeyli
2012-09-21 8:20 ` [PATCH V2 " joeyli
2012-09-28 3:20 ` Serge Hallyn
2012-09-20 14:41 ` [PATCH V2 08/10] efi: Enable secure boot lockdown automatically when enabled in firmware Matthew Garrett
2012-09-28 3:21 ` Serge Hallyn
2012-10-22 13:22 ` Matt Fleming
2012-09-20 14:41 ` [PATCH V2 09/10] acpi: Ignore acpi_rsdp kernel parameter in a secure boot environment Matthew Garrett
2012-09-20 14:41 ` [PATCH V2 10/10] SELinux: define mapping for new Secure Boot capability Matthew Garrett
2012-09-21 22:55 ` [RFC] Second attempt at kernel secure boot support Eric W. Biederman
2012-09-22 15:21 ` Matthew Garrett
2012-10-29 7:49 ` Jiri Kosina
2012-10-29 17:41 ` Matthew Garrett
2012-10-31 14:50 ` Jiri Kosina
2012-10-31 14:54 ` Josh Boyer
2012-10-31 14:59 ` Shea Levy
2012-10-31 15:55 ` Alan Cox
2012-10-31 15:55 ` Jiri Kosina
2012-10-31 17:03 ` Alan Cox
2012-10-31 17:01 ` Shea Levy
2012-10-31 17:17 ` Alan Cox
2012-10-31 17:10 ` Matthew Garrett
2012-10-31 17:21 ` Alan Cox
2012-10-31 17:17 ` Matthew Garrett
2012-10-31 17:39 ` Alan Cox
2012-10-31 17:37 ` Matthew Garrett
2012-10-31 17:49 ` Alan Cox
2012-10-31 17:45 ` Matthew Garrett
2012-10-31 20:14 ` Oliver Neukum
2012-10-31 21:58 ` Chris Friesen
2012-10-31 22:00 ` Jiri Kosina
2012-10-31 22:19 ` Oliver Neukum
2012-11-01 9:08 ` James Bottomley
2012-11-01 9:20 ` Jiri Kosina
2012-11-01 9:38 ` James Bottomley
2012-11-01 9:45 ` Jiri Kosina
2012-11-01 9:59 ` James Bottomley
2012-11-01 10:06 ` Jiri Kosina
2012-11-01 14:29 ` Eric Paris
2012-11-01 14:42 ` James Bottomley
2012-11-01 14:49 ` Matthew Garrett
2012-11-01 15:06 ` James Bottomley
2012-11-01 15:17 ` Eric Paris
2012-11-01 16:26 ` Matthew Garrett
2012-11-01 15:06 ` Alan Cox
2012-11-01 16:29 ` Matthew Garrett
2012-11-01 16:40 ` Alan Cox
2012-11-01 14:59 ` Eric Paris
2012-11-01 15:11 ` Alan Cox
2012-11-01 15:18 ` James Bottomley
2012-11-01 17:50 ` Eric Paris
2012-11-01 21:03 ` James Bottomley
2012-11-01 21:06 ` Matthew Garrett
2012-11-01 21:14 ` James Bottomley
2012-11-01 21:18 ` Matthew Garrett
2012-11-01 21:35 ` Alan Cox
2012-11-01 21:31 ` Alan Cox
2012-11-01 21:28 ` Matthew Garrett
2012-11-01 21:37 ` Alan Cox
2012-11-01 21:34 ` Matthew Garrett
2012-11-01 21:58 ` Alan Cox
2012-11-01 21:57 ` Matthew Garrett
2012-11-02 8:49 ` Eric W. Biederman
2012-11-02 14:00 ` Matthew Garrett
2012-11-02 22:03 ` Eric W. Biederman
2012-11-02 22:19 ` Chris Friesen
2012-11-02 23:46 ` Alan Cox
2012-11-03 0:23 ` Matthew Garrett
2012-11-03 0:55 ` Alan Cox
2012-11-03 0:20 ` Matthew Garrett
2012-11-03 0:47 ` Eric W. Biederman
2012-11-03 1:03 ` Alan Cox
2012-11-03 1:43 ` Matthew Garrett
2012-11-03 16:31 ` Alan Cox
2012-11-03 16:37 ` Matthew Garrett
2012-11-03 16:37 ` Eric Paris
2012-11-03 16:42 ` Matthew Garrett
2012-11-02 17:19 ` Vivek Goyal
2012-11-01 14:46 ` Alan Cox
2012-11-01 15:04 ` Eric Paris
2012-11-01 20:27 ` Pavel Machek
2012-11-01 21:02 ` Chris Friesen
2012-11-02 15:48 ` Vivek Goyal
2012-11-02 16:54 ` Chris Friesen
2012-11-02 17:03 ` Vivek Goyal
2012-11-03 23:09 ` Jiri Kosina
2012-11-05 6:38 ` Eric W. Biederman
2012-11-05 14:40 ` Jiri Kosina
2012-11-05 15:31 ` Jiri Kosina
2012-11-05 15:37 ` Chris Friesen
2012-11-05 18:22 ` Vivek Goyal
2012-11-02 16:33 ` Pavel Machek
2012-11-02 16:52 ` James Bottomley
2012-11-02 16:54 ` Matthew Garrett
2012-11-02 17:48 ` James Bottomley
2012-11-02 17:54 ` Matthew Garrett
2012-11-02 17:57 ` James Bottomley
2012-11-02 18:04 ` Matthew Garrett
2012-11-02 19:18 ` Eric Paris
2012-11-02 23:38 ` James Bottomley
2012-11-03 0:22 ` Matthew Garrett
2012-11-03 12:03 ` James Bottomley
2012-11-03 13:46 ` Matthew Garrett
2012-11-03 22:56 ` James Bottomley
2012-11-04 4:28 ` Matthew Garrett
2012-11-04 9:14 ` James Bottomley
2012-11-04 13:52 ` Matthew Garrett
2012-11-05 6:14 ` Eric W. Biederman
2012-11-05 7:12 ` H. Peter Anvin
2012-11-05 7:24 ` Eric W. Biederman
2012-11-05 7:40 ` H. Peter Anvin
2012-11-05 8:50 ` Eric W. Biederman
2012-11-05 8:53 ` H. Peter Anvin
2012-11-05 12:38 ` Matthew Garrett
2012-11-05 13:44 ` Alan Cox
2012-11-05 13:46 ` Matthew Garrett
2012-11-05 19:16 ` Eric W. Biederman
2012-11-05 20:25 ` Matthew Garrett
2012-11-06 2:46 ` Eric W. Biederman
2012-11-06 3:12 ` Matthew Garrett
2012-11-06 3:36 ` Eric W. Biederman
2012-11-06 3:53 ` Matthew Garrett
2012-11-06 5:19 ` Eric W. Biederman
2012-11-06 5:34 ` Matthew Garrett
2012-11-06 7:56 ` Florian Weimer
2012-11-06 15:14 ` Chris Friesen
2012-11-06 15:19 ` Jiri Kosina
2012-11-06 21:51 ` Florian Weimer
2012-11-06 21:55 ` Matthew Garrett
2012-11-06 22:06 ` Florian Weimer
2012-11-06 22:31 ` Matthew Garrett
2012-11-06 22:49 ` Alan Cox
2012-11-06 22:47 ` Matthew Garrett
[not found] ` <CAMFK0gt7oAr4ArD8FmD8QE+i4g4rSTmQjbbLcjs02xwQeXGx-A@mail.gmail.com>
2012-11-07 14:55 ` Matthew Garrett
2012-11-08 10:18 ` James Courtier-Dutton
[not found] ` <CAAMvbhFF=kb8TJ4oE+40Zrx7HD1OkD0NOYj7QEZegZKGtqDm_A@mail.gmail.com>
2012-11-08 11:19 ` Alan Cox
2012-11-06 9:12 ` Alan Cox
2012-11-06 13:17 ` Matthew Garrett
2012-11-06 8:13 ` Valdis.Kletnieks
2012-11-05 8:20 ` James Bottomley
2012-11-05 12:36 ` Matthew Garrett
2012-11-04 11:53 ` Pavel Machek
2012-11-05 21:25 ` Florian Weimer
2012-11-02 14:55 ` Vivek Goyal
2012-11-01 10:12 ` Oliver Neukum
2012-10-31 17:21 ` Jiri Kosina
2012-10-31 15:56 ` Matthew Garrett
2012-10-31 17:08 ` Alan Cox
2012-10-31 17:08 ` Shea Levy
2012-10-31 16:04 ` Jiri Kosina
2012-10-31 16:10 ` Josh Boyer
2012-10-31 15:02 ` Matthew Garrett
2012-10-31 15:05 ` Shea Levy
2012-10-31 15:09 ` Matthew Garrett
2012-11-02 15:30 ` Vivek Goyal
2012-11-02 15:42 ` Matthew Garrett
2012-11-02 15:52 ` Vivek Goyal
2012-11-02 16:22 ` Jiri Kosina
2012-11-02 18:30 ` Vivek Goyal
2012-11-02 16:35 ` Shuah Khan
2012-11-06 12:51 ` Jiri Kosina
2012-11-06 13:16 ` Matthew Garrett
2012-10-31 17:28 ` Takashi Iwai
2012-10-31 17:37 ` Matthew Garrett
2012-10-31 17:44 ` Alan Cox
2012-10-31 17:44 ` Matthew Garrett
2012-10-31 18:53 ` Takashi Iwai
2012-11-01 4:21 ` joeyli
2012-11-01 13:18 ` Alan Cox
2012-11-05 17:13 ` Takashi Iwai
2012-11-05 17:18 ` [PATCH RFC 0/4] Add firmware signature file check Takashi Iwai
2012-11-05 17:19 ` [PATCH RFC 1/4] scripts/sign-file: Allow specifying hash algorithm via -a option Takashi Iwai
2012-11-05 17:19 ` [PATCH RFC 2/4] scripts/sign-file: Support firmware signing Takashi Iwai
2012-11-05 17:20 ` [PATCH RFC 3/4] firmware: Add a signature check Takashi Iwai
2012-11-06 6:03 ` Mimi Zohar [this message]
2012-11-05 17:20 ` [PATCH RFC 4/4] firmware: Install signature files automatically Takashi Iwai
2012-11-05 18:12 ` [PATCH RFC 0/4] Add firmware signature file check Takashi Iwai
2012-11-05 20:43 ` Josh Boyer
2012-11-06 6:46 ` Takashi Iwai
2012-11-06 9:20 ` Alan Cox
2012-11-06 10:05 ` Takashi Iwai
2012-11-06 0:01 ` David Howells
2012-11-06 0:05 ` David Howells
2012-11-06 7:01 ` Takashi Iwai
2012-11-06 2:30 ` Ming Lei
2012-11-06 5:46 ` lee joey
2012-11-06 7:03 ` Takashi Iwai
2012-11-06 7:16 ` Ming Lei
2012-11-06 7:32 ` Takashi Iwai
2012-11-06 8:04 ` Ming Lei
2012-11-06 8:18 ` Takashi Iwai
2012-11-06 10:04 ` Ming Lei
2012-11-06 10:17 ` Takashi Iwai
2012-11-06 10:40 ` Ming Lei
2012-11-06 10:53 ` Takashi Iwai
2012-11-06 11:03 ` Ming Lei
2012-11-06 11:15 ` Alan Cox
[not found] ` <CAGB3EUTrSMDhja9Gu3h7nuZX+H2_owp8MnUNwbZuCW=_GuawqQ@mail.gmail.com>
2012-11-06 7:06 ` Takashi Iwai
2012-11-06 7:30 ` Ming Lei
2012-11-08 17:35 ` [PATCH RFC v2 " Takashi Iwai
2012-11-08 17:35 ` [PATCH RFC v2 1/4] firmware: Add the firmware signing support to scripts/sign-file Takashi Iwai
2012-11-23 6:51 ` joeyli
2012-11-08 17:35 ` [PATCH RFC v2 2/4] firmware: Add -a option " Takashi Iwai
2012-11-23 6:51 ` joeyli
2012-11-08 17:35 ` [PATCH RFC v2 3/4] firmware: Add support for signature checks Takashi Iwai
2012-11-23 6:56 ` joeyli
2012-11-23 7:34 ` Takashi Iwai
2012-11-08 17:35 ` [PATCH RFC v2 4/4] firmware: Install firmware signature files automatically Takashi Iwai
2012-11-23 6:52 ` joeyli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1352181784.8752.27.camel@falcor \
--to=zohar@linux.vnet.ibm.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=dhowells@redhat.com \
--cc=jkosina@suse.cz \
--cc=jlee@suse.com \
--cc=linux-efi@vger.ke \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
--cc=rusty@rustcorp.com.au \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox