diff options
-rw-r--r-- | security/integrity/Kconfig | 14 | ||||
-rw-r--r-- | security/integrity/Makefile | 1 | ||||
-rw-r--r-- | security/integrity/digsig.c | 48 | ||||
-rw-r--r-- | security/integrity/integrity.h | 21 |
4 files changed, 84 insertions, 0 deletions
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index 4bf00acf7937..d87fa2a8fa3b 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig | |||
@@ -3,5 +3,19 @@ config INTEGRITY | |||
3 | def_bool y | 3 | def_bool y |
4 | depends on IMA || EVM | 4 | depends on IMA || EVM |
5 | 5 | ||
6 | config INTEGRITY_DIGSIG | ||
7 | boolean "Digital signature verification using multiple keyrings" | ||
8 | depends on INTEGRITY | ||
9 | default n | ||
10 | select DIGSIG | ||
11 | help | ||
12 | This option enables digital signature verification support | ||
13 | using multiple keyrings. It defines separate keyrings for each | ||
14 | of the different use cases - evm, ima, and modules. | ||
15 | Different keyrings improves search performance, but also allow | ||
16 | to "lock" certain keyring to prevent adding new keys. | ||
17 | This is useful for evm and module keyrings, when keys are | ||
18 | usually only added from initramfs. | ||
19 | |||
6 | source security/integrity/ima/Kconfig | 20 | source security/integrity/ima/Kconfig |
7 | source security/integrity/evm/Kconfig | 21 | source security/integrity/evm/Kconfig |
diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 0ae44aea6516..bece0563ee5e 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_INTEGRITY) += integrity.o | 5 | obj-$(CONFIG_INTEGRITY) += integrity.o |
6 | obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o | ||
6 | 7 | ||
7 | integrity-y := iint.o | 8 | integrity-y := iint.o |
8 | 9 | ||
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c new file mode 100644 index 000000000000..2dc167d7cde9 --- /dev/null +++ b/security/integrity/digsig.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Intel Corporation | ||
3 | * | ||
4 | * Author: | ||
5 | * Dmitry Kasatkin <dmitry.kasatkin@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, version 2 of the License. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
15 | #include <linux/err.h> | ||
16 | #include <linux/rbtree.h> | ||
17 | #include <linux/key-type.h> | ||
18 | #include <linux/digsig.h> | ||
19 | |||
20 | #include "integrity.h" | ||
21 | |||
22 | static struct key *keyring[INTEGRITY_KEYRING_MAX]; | ||
23 | |||
24 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { | ||
25 | "_evm", | ||
26 | "_module", | ||
27 | "_ima", | ||
28 | }; | ||
29 | |||
30 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | ||
31 | const char *digest, int digestlen) | ||
32 | { | ||
33 | if (id >= INTEGRITY_KEYRING_MAX) | ||
34 | return -EINVAL; | ||
35 | |||
36 | if (!keyring[id]) { | ||
37 | keyring[id] = | ||
38 | request_key(&key_type_keyring, keyring_name[id], NULL); | ||
39 | if (IS_ERR(keyring[id])) { | ||
40 | int err = PTR_ERR(keyring[id]); | ||
41 | pr_err("no %s keyring: %d\n", keyring_name[id], err); | ||
42 | keyring[id] = NULL; | ||
43 | return err; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | return digsig_verify(keyring[id], sig, siglen, digest, digestlen); | ||
48 | } | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 3143a3c39868..4da6ba81d153 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -46,5 +46,26 @@ struct integrity_iint_cache { | |||
46 | struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); | 46 | struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); |
47 | struct integrity_iint_cache *integrity_iint_find(struct inode *inode); | 47 | struct integrity_iint_cache *integrity_iint_find(struct inode *inode); |
48 | 48 | ||
49 | #define INTEGRITY_KEYRING_EVM 0 | ||
50 | #define INTEGRITY_KEYRING_MODULE 1 | ||
51 | #define INTEGRITY_KEYRING_IMA 2 | ||
52 | #define INTEGRITY_KEYRING_MAX 3 | ||
53 | |||
54 | #ifdef CONFIG_INTEGRITY_DIGSIG | ||
55 | |||
56 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | ||
57 | const char *digest, int digestlen); | ||
58 | |||
59 | #else | ||
60 | |||
61 | static inline int integrity_digsig_verify(const unsigned int id, | ||
62 | const char *sig, int siglen, | ||
63 | const char *digest, int digestlen) | ||
64 | { | ||
65 | return -EOPNOTSUPP; | ||
66 | } | ||
67 | |||
68 | #endif /* CONFIG_INTEGRITY_DIGSIG */ | ||
69 | |||
49 | /* set during initialization */ | 70 | /* set during initialization */ |
50 | extern int iint_initialized; | 71 | extern int iint_initialized; |