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 *keyring_name[INTEGRITY_KEYRING_MAX] = { 30 #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING 31 "_evm", 32 "_ima", 33 #else 34 ".evm", 35 ".ima", 36 #endif 37 "_module", 38 }; 39 40 #ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING 41 static bool init_keyring __initdata = true; 42 #else 43 static bool init_keyring __initdata; 44 #endif 45 46 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY 47 #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted 48 #else 49 #define restrict_link_to_ima restrict_link_by_builtin_trusted 50 #endif 51 52 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 53 const char *digest, int digestlen) 54 { 55 if (id >= INTEGRITY_KEYRING_MAX || siglen < 2) 56 return -EINVAL; 57 58 if (!keyring[id]) { 59 keyring[id] = 60 request_key(&key_type_keyring, keyring_name[id], NULL); 61 if (IS_ERR(keyring[id])) { 62 int err = PTR_ERR(keyring[id]); 63 pr_err("no %s keyring: %d\n", keyring_name[id], err); 64 keyring[id] = NULL; 65 return err; 66 } 67 } 68 69 switch (sig[1]) { 70 case 1: 71 /* v1 API expect signature without xattr type */ 72 return digsig_verify(keyring[id], sig + 1, siglen - 1, 73 digest, digestlen); 74 case 2: 75 return asymmetric_verify(keyring[id], sig, siglen, 76 digest, digestlen); 77 } 78 79 return -EOPNOTSUPP; 80 } 81 82 int __init integrity_init_keyring(const unsigned int id) 83 { 84 const struct cred *cred = current_cred(); 85 struct key_restriction *restriction; 86 int err = 0; 87 88 if (!init_keyring) 89 return 0; 90 91 restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); 92 if (!restriction) 93 return -ENOMEM; 94 95 restriction->check = restrict_link_to_ima; 96 97 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 98 KGIDT_INIT(0), cred, 99 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 100 KEY_USR_VIEW | KEY_USR_READ | 101 KEY_USR_WRITE | KEY_USR_SEARCH), 102 KEY_ALLOC_NOT_IN_QUOTA, 103 restriction, NULL); 104 if (IS_ERR(keyring[id])) { 105 err = PTR_ERR(keyring[id]); 106 pr_info("Can't allocate %s keyring (%d)\n", 107 keyring_name[id], err); 108 keyring[id] = NULL; 109 } 110 return err; 111 } 112 113 int __init integrity_load_x509(const unsigned int id, const char *path) 114 { 115 key_ref_t key; 116 void *data; 117 loff_t size; 118 int rc; 119 120 if (!keyring[id]) 121 return -EINVAL; 122 123 rc = kernel_read_file_from_path(path, &data, &size, 0, 124 READING_X509_CERTIFICATE); 125 if (rc < 0) { 126 pr_err("Unable to open file: %s (%d)", path, rc); 127 return rc; 128 } 129 130 key = key_create_or_update(make_key_ref(keyring[id], 1), 131 "asymmetric", 132 NULL, 133 data, 134 size, 135 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 136 KEY_USR_VIEW | KEY_USR_READ), 137 KEY_ALLOC_NOT_IN_QUOTA); 138 if (IS_ERR(key)) { 139 rc = PTR_ERR(key); 140 pr_err("Problem loading X.509 certificate (%d): %s\n", 141 rc, path); 142 } else { 143 pr_notice("Loaded X.509 cert '%s': %s\n", 144 key_ref_to_ptr(key)->description, path); 145 key_ref_put(key); 146 } 147 vfree(data); 148 return 0; 149 } 150