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 "_evm", 28 "_module", 29 #ifndef CONFIG_IMA_TRUSTED_KEYRING 30 "_ima", 31 #else 32 ".ima", 33 #endif 34 }; 35 36 int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, 37 const char *digest, int digestlen) 38 { 39 if (id >= INTEGRITY_KEYRING_MAX) 40 return -EINVAL; 41 42 if (!keyring[id]) { 43 keyring[id] = 44 request_key(&key_type_keyring, keyring_name[id], NULL); 45 if (IS_ERR(keyring[id])) { 46 int err = PTR_ERR(keyring[id]); 47 pr_err("no %s keyring: %d\n", keyring_name[id], err); 48 keyring[id] = NULL; 49 return err; 50 } 51 } 52 53 switch (sig[1]) { 54 case 1: 55 /* v1 API expect signature without xattr type */ 56 return digsig_verify(keyring[id], sig + 1, siglen - 1, 57 digest, digestlen); 58 case 2: 59 return asymmetric_verify(keyring[id], sig, siglen, 60 digest, digestlen); 61 } 62 63 return -EOPNOTSUPP; 64 } 65 66 int __init integrity_init_keyring(const unsigned int id) 67 { 68 const struct cred *cred = current_cred(); 69 int err = 0; 70 71 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 72 KGIDT_INIT(0), cred, 73 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 74 KEY_USR_VIEW | KEY_USR_READ | 75 KEY_USR_WRITE | KEY_USR_SEARCH), 76 KEY_ALLOC_NOT_IN_QUOTA, NULL); 77 if (!IS_ERR(keyring[id])) 78 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); 79 else { 80 err = PTR_ERR(keyring[id]); 81 pr_info("Can't allocate %s keyring (%d)\n", 82 keyring_name[id], err); 83 keyring[id] = NULL; 84 } 85 return err; 86 } 87 88 int __init integrity_load_x509(const unsigned int id, const char *path) 89 { 90 key_ref_t key; 91 char *data; 92 int rc; 93 94 if (!keyring[id]) 95 return -EINVAL; 96 97 rc = integrity_read_file(path, &data); 98 if (rc < 0) 99 return rc; 100 101 key = key_create_or_update(make_key_ref(keyring[id], 1), 102 "asymmetric", 103 NULL, 104 data, 105 rc, 106 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 107 KEY_USR_VIEW | KEY_USR_READ), 108 KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_TRUSTED); 109 if (IS_ERR(key)) { 110 rc = PTR_ERR(key); 111 pr_err("Problem loading X.509 certificate (%d): %s\n", 112 rc, path); 113 } else { 114 pr_notice("Loaded X.509 cert '%s': %s\n", 115 key_ref_to_ptr(key)->description, path); 116 key_ref_put(key); 117 } 118 kfree(data); 119 return 0; 120 } 121