1 /* 2 * Copyright (C) 2010 IBM Corporation 3 * 4 * Authors: 5 * Mimi Zohar <zohar@us.ibm.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 * File: evm_secfs.c 12 * - Used to signal when key is on keyring 13 * - Get the key and enable EVM 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include <linux/uaccess.h> 19 #include <linux/module.h> 20 #include "evm.h" 21 22 static struct dentry *evm_init_tpm; 23 24 /** 25 * evm_read_key - read() for <securityfs>/evm 26 * 27 * @filp: file pointer, not actually used 28 * @buf: where to put the result 29 * @count: maximum to send along 30 * @ppos: where to start 31 * 32 * Returns number of bytes read or error code, as appropriate 33 */ 34 static ssize_t evm_read_key(struct file *filp, char __user *buf, 35 size_t count, loff_t *ppos) 36 { 37 char temp[80]; 38 ssize_t rc; 39 40 if (*ppos != 0) 41 return 0; 42 43 sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP)); 44 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 45 46 return rc; 47 } 48 49 /** 50 * evm_write_key - write() for <securityfs>/evm 51 * @file: file pointer, not actually used 52 * @buf: where to get the data from 53 * @count: bytes sent 54 * @ppos: where to start 55 * 56 * Used to signal that key is on the kernel key ring. 57 * - get the integrity hmac key from the kernel key ring 58 * - create list of hmac protected extended attributes 59 * Returns number of bytes written or error code, as appropriate 60 */ 61 static ssize_t evm_write_key(struct file *file, const char __user *buf, 62 size_t count, loff_t *ppos) 63 { 64 int i, ret; 65 66 if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP)) 67 return -EPERM; 68 69 ret = kstrtoint_from_user(buf, count, 0, &i); 70 71 if (ret) 72 return ret; 73 74 /* Reject invalid values */ 75 if (!i || (i & ~EVM_INIT_MASK) != 0) 76 return -EINVAL; 77 78 if (i & EVM_INIT_HMAC) { 79 ret = evm_init_key(); 80 if (ret != 0) 81 return ret; 82 /* Forbid further writes after the symmetric key is loaded */ 83 i |= EVM_SETUP; 84 } 85 86 evm_initialized |= i; 87 88 return count; 89 } 90 91 static const struct file_operations evm_key_ops = { 92 .read = evm_read_key, 93 .write = evm_write_key, 94 }; 95 96 int __init evm_init_secfs(void) 97 { 98 int error = 0; 99 100 evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP, 101 NULL, NULL, &evm_key_ops); 102 if (!evm_init_tpm || IS_ERR(evm_init_tpm)) 103 error = -EFAULT; 104 return error; 105 } 106