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 22 #include "integrity.h" 23 24 static struct key *keyring[INTEGRITY_KEYRING_MAX]; 25 26 static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { 27 #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING 28 "_evm", 29 "_ima", 30 #else 31 ".evm", 32 ".ima", 33 #endif 34 "_module", 35 }; 36 37 #ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING 38 static bool init_keyring __initdata = true; 39 #else 40 static bool init_keyring __initdata; 41 #endif 42 43 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 44 const char *digest, int digestlen) 45 { 46 if (id >= INTEGRITY_KEYRING_MAX) 47 return -EINVAL; 48 49 if (!keyring[id]) { 50 keyring[id] = 51 request_key(&key_type_keyring, keyring_name[id], 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 int __init integrity_init_keyring(const unsigned int id) 74 { 75 const struct cred *cred = current_cred(); 76 int err = 0; 77 78 if (!init_keyring) 79 return 0; 80 81 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 82 KGIDT_INIT(0), cred, 83 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 84 KEY_USR_VIEW | KEY_USR_READ | 85 KEY_USR_WRITE | KEY_USR_SEARCH), 86 KEY_ALLOC_NOT_IN_QUOTA, NULL); 87 if (!IS_ERR(keyring[id])) 88 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); 89 else { 90 err = PTR_ERR(keyring[id]); 91 pr_info("Can't allocate %s keyring (%d)\n", 92 keyring_name[id], err); 93 keyring[id] = NULL; 94 } 95 return err; 96 } 97 98 int __init integrity_load_x509(const unsigned int id, const char *path) 99 { 100 key_ref_t key; 101 char *data; 102 int rc; 103 104 if (!keyring[id]) 105 return -EINVAL; 106 107 rc = integrity_read_file(path, &data); 108 if (rc < 0) 109 return rc; 110 111 key = key_create_or_update(make_key_ref(keyring[id], 1), 112 "asymmetric", 113 NULL, 114 data, 115 rc, 116 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 117 KEY_USR_VIEW | KEY_USR_READ), 118 KEY_ALLOC_NOT_IN_QUOTA); 119 if (IS_ERR(key)) { 120 rc = PTR_ERR(key); 121 pr_err("Problem loading X.509 certificate (%d): %s\n", 122 rc, path); 123 } else { 124 pr_notice("Loaded X.509 cert '%s': %s\n", 125 key_ref_to_ptr(key)->description, path); 126 key_ref_put(key); 127 } 128 kfree(data); 129 return 0; 130 } 131