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