[RFC v2 5/7] modsig: verify module integrity based on signature

From: Dmitry Kasatkin
Date: Wed Aug 15 2012 - 14:44:07 EST


This patch adds support for verifying module integrity using the upstreamed
digital signature support. Signatures are appended to the kernel module
binary, as suggested by Rusty Russell. Using of this functionality does not
require changes to insmod and modprobe. The module hash is calculated and
verified against the signature. Public key and signature format can found
in Documentation/digsig.txt

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@xxxxxxxxx>
---
security/integrity/Kconfig | 11 ++++++
security/integrity/Makefile | 1 +
security/integrity/module.c | 91 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+)
create mode 100644 security/integrity/module.c

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index f789018..fbc7c78 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -27,5 +27,16 @@ config INTEGRITY_PUBKEY
custom built kernels, or a key used to label the entire filesystem for
EVM/IMA-appraisal.

+config INTEGRITY_MODULES
+ bool "Module integrity checking"
+ depends on SECURITY
+ select INTEGRITY_SIGNATURE
+ default n
+ help
+ This option enables module integrity checking,
+ using digital signatures
+
+ If unsure, say N.
+
source security/integrity/ima/Kconfig
source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index cf234f5..226634c 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -4,6 +4,7 @@

obj-$(CONFIG_INTEGRITY) += integrity.o
obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
+obj-$(CONFIG_INTEGRITY_MODULES) += module.o

integrity-y := iint.o

diff --git a/security/integrity/module.c b/security/integrity/module.c
new file mode 100644
index 0000000..b0e9ba2
--- /dev/null
+++ b/security/integrity/module.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011,2012 Intel Corporation
+ *
+ * Authors:
+ * Dmitry Kasatkin <dmitry.kasatkin@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * File: module.c
+ * implements the module hooks: integrity_module_check
+ */
+
+#include <linux/module.h>
+#include <linux/security.h>
+
+#include "integrity.h"
+
+static const char sig_magic[] = "This Is A Crypto Signed Module";
+static const char sig_magic_len = sizeof(sig_magic) - 1;
+
+/**
+ * integrity_module_check - check module integrity
+ * @hdr: module data
+ * @len: length of the module
+ * @return: length without signature, error code on failure
+ *
+ * Hook to verify module integrity.
+ *
+ */
+int integrity_module_check(const void *hdr, unsigned long len)
+{
+ u8 digest[SHA1_DIGEST_SIZE];
+ int rc = -EINVAL, siglen;
+ char *tmp;
+
+ if (len < sig_magic_len + 2) {
+ pr_err("MODSIG: signature magic is missing\n");
+ goto err1;
+ }
+
+ tmp = (char *)hdr + len;
+
+ len -= sig_magic_len;
+ tmp -= sig_magic_len;
+ if (memcmp(tmp, sig_magic, sig_magic_len)) {
+ pr_err("MODSIG: wrong signature magic\n");
+ goto err1;
+ }
+
+ /* set to lenth */
+ len -= 2;
+ tmp -= 2;
+ siglen = __be16_to_cpup((u16 *)tmp);
+
+ if (len < siglen) {
+ pr_err("MODSIG: wrong signature\n");
+ goto err1;
+ }
+
+ len -= siglen;
+ tmp -= siglen;
+
+ rc = integrity_calc_digest("sha1", hdr, len, digest);
+ if (rc < 0)
+ goto err1;
+
+ rc = integrity_digsig_verify(INTEGRITY_KEYRING_MODULE, tmp, siglen,
+ digest, sizeof(digest));
+ if (rc) {
+ pr_err("MODSIG: module verification failed: %d", rc);
+ print_hex_dump(KERN_ERR, "hash: ", DUMP_PREFIX_NONE, 32, 1,
+ digest, sizeof(digest), 0);
+ goto err1;
+ }
+ rc = len;
+err1:
+ return rc;
+}
+
+static int __init module_check_init(void)
+{
+ return 0;
+}
+
+late_initcall(module_check_init);
+
+MODULE_DESCRIPTION("Module integrity verification");
+MODULE_LICENSE("GPL");
--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/