~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/integrity/digsig.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (C) 2011 Intel Corporation
  4  *
  5  * Author:
  6  * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
  7  */
  8 
  9 #include <linux/err.h>
 10 #include <linux/sched.h>
 11 #include <linux/slab.h>
 12 #include <linux/cred.h>
 13 #include <linux/kernel_read_file.h>
 14 #include <linux/key-type.h>
 15 #include <linux/digsig.h>
 16 #include <linux/vmalloc.h>
 17 #include <crypto/public_key.h>
 18 #include <keys/system_keyring.h>
 19 
 20 #include "integrity.h"
 21 
 22 static struct key *keyring[INTEGRITY_KEYRING_MAX];
 23 
 24 static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
 25 #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
 26         "_evm",
 27         "_ima",
 28 #else
 29         ".evm",
 30         ".ima",
 31 #endif
 32         ".platform",
 33         ".machine",
 34 };
 35 
 36 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
 37 #define restrict_link_to_ima restrict_link_by_digsig_builtin_and_secondary
 38 #else
 39 #define restrict_link_to_ima restrict_link_by_digsig_builtin
 40 #endif
 41 
 42 static struct key *integrity_keyring_from_id(const unsigned int id)
 43 {
 44         if (id >= INTEGRITY_KEYRING_MAX)
 45                 return ERR_PTR(-EINVAL);
 46 
 47         if (!keyring[id]) {
 48                 keyring[id] =
 49                         request_key(&key_type_keyring, keyring_name[id], NULL);
 50                 if (IS_ERR(keyring[id])) {
 51                         int err = PTR_ERR(keyring[id]);
 52                         pr_err("no %s keyring: %d\n", keyring_name[id], err);
 53                         keyring[id] = NULL;
 54                         return ERR_PTR(err);
 55                 }
 56         }
 57 
 58         return keyring[id];
 59 }
 60 
 61 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
 62                             const char *digest, int digestlen)
 63 {
 64         struct key *keyring;
 65 
 66         if (siglen < 2)
 67                 return -EINVAL;
 68 
 69         keyring = integrity_keyring_from_id(id);
 70         if (IS_ERR(keyring))
 71                 return PTR_ERR(keyring);
 72 
 73         switch (sig[1]) {
 74         case 1:
 75                 /* v1 API expect signature without xattr type */
 76                 return digsig_verify(keyring, sig + 1, siglen - 1, digest,
 77                                      digestlen);
 78         case 2: /* regular file data hash based signature */
 79         case 3: /* struct ima_file_id data based signature */
 80                 return asymmetric_verify(keyring, sig, siglen, digest,
 81                                          digestlen);
 82         }
 83 
 84         return -EOPNOTSUPP;
 85 }
 86 
 87 int integrity_modsig_verify(const unsigned int id, const struct modsig *modsig)
 88 {
 89         struct key *keyring;
 90 
 91         keyring = integrity_keyring_from_id(id);
 92         if (IS_ERR(keyring))
 93                 return PTR_ERR(keyring);
 94 
 95         return ima_modsig_verify(keyring, modsig);
 96 }
 97 
 98 static int __init __integrity_init_keyring(const unsigned int id,
 99                                            key_perm_t perm,
100                                            struct key_restriction *restriction)
101 {
102         const struct cred *cred = current_cred();
103         int err = 0;
104 
105         keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
106                                     KGIDT_INIT(0), cred, perm,
107                                     KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
108         if (IS_ERR(keyring[id])) {
109                 err = PTR_ERR(keyring[id]);
110                 pr_info("Can't allocate %s keyring (%d)\n",
111                         keyring_name[id], err);
112                 keyring[id] = NULL;
113         } else {
114                 if (id == INTEGRITY_KEYRING_PLATFORM)
115                         set_platform_trusted_keys(keyring[id]);
116                 if (id == INTEGRITY_KEYRING_MACHINE && imputed_trust_enabled())
117                         set_machine_trusted_keys(keyring[id]);
118                 if (id == INTEGRITY_KEYRING_IMA)
119                         load_module_cert(keyring[id]);
120         }
121 
122         return err;
123 }
124 
125 int __init integrity_init_keyring(const unsigned int id)
126 {
127         struct key_restriction *restriction;
128         key_perm_t perm;
129         int ret;
130 
131         perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
132                 | KEY_USR_READ | KEY_USR_SEARCH;
133 
134         if (id == INTEGRITY_KEYRING_PLATFORM ||
135             (id == INTEGRITY_KEYRING_MACHINE &&
136             !IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING))) {
137                 restriction = NULL;
138                 goto out;
139         }
140 
141         if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
142                 return 0;
143 
144         restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
145         if (!restriction)
146                 return -ENOMEM;
147 
148         if (id == INTEGRITY_KEYRING_MACHINE)
149                 restriction->check = restrict_link_by_ca;
150         else
151                 restriction->check = restrict_link_to_ima;
152 
153         /*
154          * MOK keys can only be added through a read-only runtime services
155          * UEFI variable during boot. No additional keys shall be allowed to
156          * load into the machine keyring following init from userspace.
157          */
158         if (id != INTEGRITY_KEYRING_MACHINE)
159                 perm |= KEY_USR_WRITE;
160 
161 out:
162         ret = __integrity_init_keyring(id, perm, restriction);
163         if (ret)
164                 kfree(restriction);
165         return ret;
166 }
167 
168 static int __init integrity_add_key(const unsigned int id, const void *data,
169                                     off_t size, key_perm_t perm)
170 {
171         key_ref_t key;
172         int rc = 0;
173 
174         if (!keyring[id])
175                 return -EINVAL;
176 
177         key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
178                                    NULL, data, size, perm,
179                                    KEY_ALLOC_NOT_IN_QUOTA);
180         if (IS_ERR(key)) {
181                 rc = PTR_ERR(key);
182                 if (id != INTEGRITY_KEYRING_MACHINE)
183                         pr_err("Problem loading X.509 certificate %d\n", rc);
184         } else {
185                 pr_notice("Loaded X.509 cert '%s'\n",
186                           key_ref_to_ptr(key)->description);
187                 key_ref_put(key);
188         }
189 
190         return rc;
191 
192 }
193 
194 int __init integrity_load_x509(const unsigned int id, const char *path)
195 {
196         void *data = NULL;
197         size_t size;
198         int rc;
199         key_perm_t perm;
200 
201         rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
202                                         READING_X509_CERTIFICATE);
203         if (rc < 0) {
204                 pr_err("Unable to open file: %s (%d)", path, rc);
205                 return rc;
206         }
207         size = rc;
208 
209         perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
210 
211         pr_info("Loading X.509 certificate: %s\n", path);
212         rc = integrity_add_key(id, (const void *)data, size, perm);
213 
214         vfree(data);
215         return rc;
216 }
217 
218 int __init integrity_load_cert(const unsigned int id, const char *source,
219                                const void *data, size_t len, key_perm_t perm)
220 {
221         if (!data)
222                 return -EINVAL;
223 
224         pr_info("Loading X.509 certificate: %s\n", source);
225         return integrity_add_key(id, data, len, perm);
226 }
227 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php