integrity: digital signature verification using multiple keyrings
authorDmitry Kasatkin <dmitry.kasatkin@intel.com>
Wed, 5 Oct 2011 08:54:46 +0000 (11:54 +0300)
committerDmitry Kasatkin <dmitry.kasatkin@intel.com>
Wed, 9 Nov 2011 14:51:09 +0000 (16:51 +0200)
Define separate keyrings for each of the different use cases - evm, ima,
and modules. Using different keyrings improves search performance, and also
allows "locking" specific keyring to prevent adding new keys.
This is useful for evm and module keyrings, when keys are usually only
added from initramfs.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
security/integrity/Kconfig
security/integrity/Makefile
security/integrity/digsig.c [new file with mode: 0644]
security/integrity/integrity.h

index 4bf00acf7937cf35afba531709841038b961b7c5..d87fa2a8fa3bb67f2b2caea1d6b1aa5c46337dba 100644 (file)
@@ -3,5 +3,19 @@ config INTEGRITY
        def_bool y
        depends on IMA || EVM
 
+config INTEGRITY_DIGSIG
+       boolean "Digital signature verification using multiple keyrings"
+       depends on INTEGRITY
+       default n
+       select DIGSIG
+       help
+         This option enables digital signature verification support
+         using multiple keyrings. It defines separate keyrings for each
+         of the different use cases - evm, ima, and modules.
+         Different keyrings improves search performance, but also allow
+         to "lock" certain keyring to prevent adding new keys.
+         This is useful for evm and module keyrings, when keys are
+         usually only added from initramfs.
+
 source security/integrity/ima/Kconfig
 source security/integrity/evm/Kconfig
index 0ae44aea6516680f20bd1e513ab4c8d3a73f0b8d..bece0563ee5e019bc9fa56bd2dff4e426cf262b7 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_INTEGRITY) += integrity.o
+obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o
 
 integrity-y := iint.o
 
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
new file mode 100644 (file)
index 0000000..2dc167d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * Author:
+ * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/err.h>
+#include <linux/rbtree.h>
+#include <linux/key-type.h>
+#include <linux/digsig.h>
+
+#include "integrity.h"
+
+static struct key *keyring[INTEGRITY_KEYRING_MAX];
+
+static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
+       "_evm",
+       "_module",
+       "_ima",
+};
+
+int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
+                                       const char *digest, int digestlen)
+{
+       if (id >= INTEGRITY_KEYRING_MAX)
+               return -EINVAL;
+
+       if (!keyring[id]) {
+               keyring[id] =
+                       request_key(&key_type_keyring, keyring_name[id], NULL);
+               if (IS_ERR(keyring[id])) {
+                       int err = PTR_ERR(keyring[id]);
+                       pr_err("no %s keyring: %d\n", keyring_name[id], err);
+                       keyring[id] = NULL;
+                       return err;
+               }
+       }
+
+       return digsig_verify(keyring[id], sig, siglen, digest, digestlen);
+}
index 3143a3c39868061ef7ea0d94713f8b88df792498..4da6ba81d1532aa4690cc95b99ba682ddb0254b1 100644 (file)
@@ -46,5 +46,26 @@ struct integrity_iint_cache {
 struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
 struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 
+#define INTEGRITY_KEYRING_EVM          0
+#define INTEGRITY_KEYRING_MODULE       1
+#define INTEGRITY_KEYRING_IMA          2
+#define INTEGRITY_KEYRING_MAX          3
+
+#ifdef CONFIG_INTEGRITY_DIGSIG
+
+int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
+                                       const char *digest, int digestlen);
+
+#else
+
+static inline int integrity_digsig_verify(const unsigned int id,
+                                         const char *sig, int siglen,
+                                         const char *digest, int digestlen)
+{
+       return -EOPNOTSUPP;
+}
+
+#endif /* CONFIG_INTEGRITY_DIGSIG */
+
 /* set during initialization */
 extern int iint_initialized;