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 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 43 const char *digest, int digestlen) 44 { 45 if (id >= INTEGRITY_KEYRING_MAX || siglen < 2) 46 return -EINVAL; 47 48 if (!keyring[id]) { 49 keyring[id] = 50 request_key(&key_type_keyring, keyring_name[id], 51 NULL, NULL); 52 if (IS_ERR(keyring[id])) { 53 int err = PTR_ERR(keyring[id]); 54 pr_err("no %s keyring: %d\n", keyring_name[id], err); 55 keyring[id] = NULL; 56 return err; 57 } 58 } 59 60 switch (sig[1]) { 61 case 1: 62 /* v1 API expect signature without xattr type */ 63 return digsig_verify(keyring[id], sig + 1, siglen - 1, 64 digest, digestlen); 65 case 2: 66 return asymmetric_verify(keyring[id], sig, siglen, 67 digest, digestlen); 68 } 69 70 return -EOPNOTSUPP; 71 } 72 73 static int __init __integrity_init_keyring(const unsigned int id, 74 struct key_acl *acl, 75 struct key_restriction *restriction) 76 { 77 const struct cred *cred = current_cred(); 78 int err = 0; 79 80 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 81 KGIDT_INIT(0), cred, acl, 82 KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); 83 if (IS_ERR(keyring[id])) { 84 err = PTR_ERR(keyring[id]); 85 pr_info("Can't allocate %s keyring (%d)\n", 86 keyring_name[id], err); 87 keyring[id] = NULL; 88 } else { 89 if (id == INTEGRITY_KEYRING_PLATFORM) 90 set_platform_trusted_keys(keyring[id]); 91 } 92 93 return err; 94 } 95 96 int __init integrity_init_keyring(const unsigned int id) 97 { 98 struct key_restriction *restriction; 99 struct key_acl *acl = &internal_keyring_acl; 100 101 if (id == INTEGRITY_KEYRING_PLATFORM) { 102 restriction = NULL; 103 goto out; 104 } 105 106 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) 107 return 0; 108 109 restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); 110 if (!restriction) 111 return -ENOMEM; 112 113 restriction->check = restrict_link_to_ima; 114 acl = &internal_writable_keyring_acl; 115 116 out: 117 return __integrity_init_keyring(id, acl, restriction); 118 } 119 120 static int __init integrity_add_key(const unsigned int id, const void *data, 121 off_t size, struct key_acl *acl) 122 { 123 key_ref_t key; 124 int rc = 0; 125 126 if (!keyring[id]) 127 return -EINVAL; 128 129 key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric", 130 NULL, data, size, acl ?: &internal_key_acl, 131 KEY_ALLOC_NOT_IN_QUOTA); 132 if (IS_ERR(key)) { 133 rc = PTR_ERR(key); 134 pr_err("Problem loading X.509 certificate %d\n", rc); 135 } else { 136 pr_notice("Loaded X.509 cert '%s'\n", 137 key_ref_to_ptr(key)->description); 138 key_ref_put(key); 139 } 140 141 return rc; 142 143 } 144 145 int __init integrity_load_x509(const unsigned int id, const char *path) 146 { 147 void *data; 148 loff_t size; 149 int rc; 150 151 rc = kernel_read_file_from_path(path, &data, &size, 0, 152 READING_X509_CERTIFICATE); 153 if (rc < 0) { 154 pr_err("Unable to open file: %s (%d)", path, rc); 155 return rc; 156 } 157 158 pr_info("Loading X.509 certificate: %s\n", path); 159 rc = integrity_add_key(id, data, size, NULL); 160 161 vfree(data); 162 return rc; 163 } 164 165 int __init integrity_load_cert(const unsigned int id, const char *source, 166 const void *data, size_t len, struct key_acl *acl) 167 { 168 if (!data) 169 return -EINVAL; 170 171 pr_info("Loading X.509 certificate: %s\n", source); 172 return integrity_add_key(id, data, len, acl); 173 } 174