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 "_module", 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 int __init integrity_init_keyring(const unsigned int id) 77 { 78 const struct cred *cred = current_cred(); 79 struct key_restriction *restriction; 80 int err = 0; 81 82 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) 83 return 0; 84 85 restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); 86 if (!restriction) 87 return -ENOMEM; 88 89 restriction->check = restrict_link_to_ima; 90 91 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 92 KGIDT_INIT(0), cred, 93 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 94 KEY_USR_VIEW | KEY_USR_READ | 95 KEY_USR_WRITE | KEY_USR_SEARCH), 96 KEY_ALLOC_NOT_IN_QUOTA, 97 restriction, NULL); 98 if (IS_ERR(keyring[id])) { 99 err = PTR_ERR(keyring[id]); 100 pr_info("Can't allocate %s keyring (%d)\n", 101 keyring_name[id], err); 102 keyring[id] = NULL; 103 } 104 return err; 105 } 106 107 int __init integrity_load_x509(const unsigned int id, const char *path) 108 { 109 key_ref_t key; 110 void *data; 111 loff_t size; 112 int rc; 113 114 if (!keyring[id]) 115 return -EINVAL; 116 117 rc = kernel_read_file_from_path(path, &data, &size, 0, 118 READING_X509_CERTIFICATE); 119 if (rc < 0) { 120 pr_err("Unable to open file: %s (%d)", path, rc); 121 return rc; 122 } 123 124 key = key_create_or_update(make_key_ref(keyring[id], 1), 125 "asymmetric", 126 NULL, 127 data, 128 size, 129 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 130 KEY_USR_VIEW | KEY_USR_READ), 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): %s\n", 135 rc, path); 136 } else { 137 pr_notice("Loaded X.509 cert '%s': %s\n", 138 key_ref_to_ptr(key)->description, path); 139 key_ref_put(key); 140 } 141 vfree(data); 142 return 0; 143 } 144