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 char *data; 116 int rc; 117 118 if (!keyring[id]) 119 return -EINVAL; 120 121 rc = integrity_read_file(path, &data); 122 if (rc < 0) 123 return rc; 124 125 key = key_create_or_update(make_key_ref(keyring[id], 1), 126 "asymmetric", 127 NULL, 128 data, 129 rc, 130 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 131 KEY_USR_VIEW | KEY_USR_READ), 132 KEY_ALLOC_NOT_IN_QUOTA); 133 if (IS_ERR(key)) { 134 rc = PTR_ERR(key); 135 pr_err("Problem loading X.509 certificate (%d): %s\n", 136 rc, path); 137 } else { 138 pr_notice("Loaded X.509 cert '%s': %s\n", 139 key_ref_to_ptr(key)->description, path); 140 key_ref_put(key); 141 } 142 kfree(data); 143 return 0; 144 } 145