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