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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/err.h> 12 #include <linux/sched.h> 13 #include <linux/slab.h> 14 #include <linux/cred.h> 15 #include <linux/key-type.h> 16 #include <linux/digsig.h> 17 #include <linux/vmalloc.h> 18 #include <crypto/public_key.h> 19 #include <keys/system_keyring.h> 20 21 #include "integrity.h" 22 23 static struct key *keyring[INTEGRITY_KEYRING_MAX]; 24 25 static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { 26 #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING 27 "_evm", 28 "_ima", 29 #else 30 ".evm", 31 ".ima", 32 #endif 33 ".platform", 34 }; 35 36 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY 37 #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted 38 #else 39 #define restrict_link_to_ima restrict_link_by_builtin_trusted 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: 79 return asymmetric_verify(keyring, sig, siglen, digest, 80 digestlen); 81 } 82 83 return -EOPNOTSUPP; 84 } 85 86 int integrity_modsig_verify(const unsigned int id, const struct modsig *modsig) 87 { 88 struct key *keyring; 89 90 keyring = integrity_keyring_from_id(id); 91 if (IS_ERR(keyring)) 92 return PTR_ERR(keyring); 93 94 return ima_modsig_verify(keyring, modsig); 95 } 96 97 static int __init __integrity_init_keyring(const unsigned int id, 98 key_perm_t perm, 99 struct key_restriction *restriction) 100 { 101 const struct cred *cred = current_cred(); 102 int err = 0; 103 104 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 105 KGIDT_INIT(0), cred, perm, 106 KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); 107 if (IS_ERR(keyring[id])) { 108 err = PTR_ERR(keyring[id]); 109 pr_info("Can't allocate %s keyring (%d)\n", 110 keyring_name[id], err); 111 keyring[id] = NULL; 112 } else { 113 if (id == INTEGRITY_KEYRING_PLATFORM) 114 set_platform_trusted_keys(keyring[id]); 115 } 116 117 return err; 118 } 119 120 int __init integrity_init_keyring(const unsigned int id) 121 { 122 struct key_restriction *restriction; 123 key_perm_t perm; 124 125 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW 126 | KEY_USR_READ | KEY_USR_SEARCH; 127 128 if (id == INTEGRITY_KEYRING_PLATFORM) { 129 restriction = NULL; 130 goto out; 131 } 132 133 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) 134 return 0; 135 136 restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); 137 if (!restriction) 138 return -ENOMEM; 139 140 restriction->check = restrict_link_to_ima; 141 perm |= KEY_USR_WRITE; 142 143 out: 144 return __integrity_init_keyring(id, perm, restriction); 145 } 146 147 int __init integrity_add_key(const unsigned int id, const void *data, 148 off_t size, key_perm_t perm) 149 { 150 key_ref_t key; 151 int rc = 0; 152 153 if (!keyring[id]) 154 return -EINVAL; 155 156 key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric", 157 NULL, data, size, perm, 158 KEY_ALLOC_NOT_IN_QUOTA); 159 if (IS_ERR(key)) { 160 rc = PTR_ERR(key); 161 pr_err("Problem loading X.509 certificate %d\n", rc); 162 } else { 163 pr_notice("Loaded X.509 cert '%s'\n", 164 key_ref_to_ptr(key)->description); 165 key_ref_put(key); 166 } 167 168 return rc; 169 170 } 171 172 int __init integrity_load_x509(const unsigned int id, const char *path) 173 { 174 void *data; 175 loff_t size; 176 int rc; 177 key_perm_t perm; 178 179 rc = kernel_read_file_from_path(path, &data, &size, 0, 180 READING_X509_CERTIFICATE); 181 if (rc < 0) { 182 pr_err("Unable to open file: %s (%d)", path, rc); 183 return rc; 184 } 185 186 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ; 187 188 pr_info("Loading X.509 certificate: %s\n", path); 189 rc = integrity_add_key(id, (const void *)data, size, perm); 190 191 vfree(data); 192 return rc; 193 } 194 195 int __init integrity_load_cert(const unsigned int id, const char *source, 196 const void *data, size_t len, key_perm_t perm) 197 { 198 if (!data) 199 return -EINVAL; 200 201 pr_info("Loading X.509 certificate: %s\n", source); 202 return integrity_add_key(id, data, len, perm); 203 } 204