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