162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2005-2010 IBM Corporation 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Authors: 662306a36Sopenharmony_ci * Mimi Zohar <zohar@us.ibm.com> 762306a36Sopenharmony_ci * Kylene Hall <kjhall@us.ibm.com> 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * File: evm_crypto.c 1062306a36Sopenharmony_ci * Using root's kernel master key (kmk), calculate the HMAC 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define pr_fmt(fmt) "EVM: "fmt 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/export.h> 1662306a36Sopenharmony_ci#include <linux/crypto.h> 1762306a36Sopenharmony_ci#include <linux/xattr.h> 1862306a36Sopenharmony_ci#include <linux/evm.h> 1962306a36Sopenharmony_ci#include <keys/encrypted-type.h> 2062306a36Sopenharmony_ci#include <crypto/hash.h> 2162306a36Sopenharmony_ci#include <crypto/hash_info.h> 2262306a36Sopenharmony_ci#include "evm.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define EVMKEY "evm-key" 2562306a36Sopenharmony_ci#define MAX_KEY_SIZE 128 2662306a36Sopenharmony_cistatic unsigned char evmkey[MAX_KEY_SIZE]; 2762306a36Sopenharmony_cistatic const int evmkey_len = MAX_KEY_SIZE; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic struct crypto_shash *hmac_tfm; 3062306a36Sopenharmony_cistatic struct crypto_shash *evm_tfm[HASH_ALGO__LAST]; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic DEFINE_MUTEX(mutex); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define EVM_SET_KEY_BUSY 0 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic unsigned long evm_set_key_flags; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic const char evm_hmac[] = "hmac(sha1)"; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/** 4162306a36Sopenharmony_ci * evm_set_key() - set EVM HMAC key from the kernel 4262306a36Sopenharmony_ci * @key: pointer to a buffer with the key data 4362306a36Sopenharmony_ci * @keylen: length of the key data 4462306a36Sopenharmony_ci * 4562306a36Sopenharmony_ci * This function allows setting the EVM HMAC key from the kernel 4662306a36Sopenharmony_ci * without using the "encrypted" key subsystem keys. It can be used 4762306a36Sopenharmony_ci * by the crypto HW kernel module which has its own way of managing 4862306a36Sopenharmony_ci * keys. 4962306a36Sopenharmony_ci * 5062306a36Sopenharmony_ci * key length should be between 32 and 128 bytes long 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ciint evm_set_key(void *key, size_t keylen) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci int rc; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci rc = -EBUSY; 5762306a36Sopenharmony_ci if (test_and_set_bit(EVM_SET_KEY_BUSY, &evm_set_key_flags)) 5862306a36Sopenharmony_ci goto busy; 5962306a36Sopenharmony_ci rc = -EINVAL; 6062306a36Sopenharmony_ci if (keylen > MAX_KEY_SIZE) 6162306a36Sopenharmony_ci goto inval; 6262306a36Sopenharmony_ci memcpy(evmkey, key, keylen); 6362306a36Sopenharmony_ci evm_initialized |= EVM_INIT_HMAC; 6462306a36Sopenharmony_ci pr_info("key initialized\n"); 6562306a36Sopenharmony_ci return 0; 6662306a36Sopenharmony_ciinval: 6762306a36Sopenharmony_ci clear_bit(EVM_SET_KEY_BUSY, &evm_set_key_flags); 6862306a36Sopenharmony_cibusy: 6962306a36Sopenharmony_ci pr_err("key initialization failed\n"); 7062306a36Sopenharmony_ci return rc; 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(evm_set_key); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic struct shash_desc *init_desc(char type, uint8_t hash_algo) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci long rc; 7762306a36Sopenharmony_ci const char *algo; 7862306a36Sopenharmony_ci struct crypto_shash **tfm, *tmp_tfm; 7962306a36Sopenharmony_ci struct shash_desc *desc; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (type == EVM_XATTR_HMAC) { 8262306a36Sopenharmony_ci if (!(evm_initialized & EVM_INIT_HMAC)) { 8362306a36Sopenharmony_ci pr_err_once("HMAC key is not set\n"); 8462306a36Sopenharmony_ci return ERR_PTR(-ENOKEY); 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci tfm = &hmac_tfm; 8762306a36Sopenharmony_ci algo = evm_hmac; 8862306a36Sopenharmony_ci } else { 8962306a36Sopenharmony_ci if (hash_algo >= HASH_ALGO__LAST) 9062306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci tfm = &evm_tfm[hash_algo]; 9362306a36Sopenharmony_ci algo = hash_algo_name[hash_algo]; 9462306a36Sopenharmony_ci } 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci if (*tfm) 9762306a36Sopenharmony_ci goto alloc; 9862306a36Sopenharmony_ci mutex_lock(&mutex); 9962306a36Sopenharmony_ci if (*tfm) 10062306a36Sopenharmony_ci goto unlock; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci tmp_tfm = crypto_alloc_shash(algo, 0, CRYPTO_NOLOAD); 10362306a36Sopenharmony_ci if (IS_ERR(tmp_tfm)) { 10462306a36Sopenharmony_ci pr_err("Can not allocate %s (reason: %ld)\n", algo, 10562306a36Sopenharmony_ci PTR_ERR(tmp_tfm)); 10662306a36Sopenharmony_ci mutex_unlock(&mutex); 10762306a36Sopenharmony_ci return ERR_CAST(tmp_tfm); 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci if (type == EVM_XATTR_HMAC) { 11062306a36Sopenharmony_ci rc = crypto_shash_setkey(tmp_tfm, evmkey, evmkey_len); 11162306a36Sopenharmony_ci if (rc) { 11262306a36Sopenharmony_ci crypto_free_shash(tmp_tfm); 11362306a36Sopenharmony_ci mutex_unlock(&mutex); 11462306a36Sopenharmony_ci return ERR_PTR(rc); 11562306a36Sopenharmony_ci } 11662306a36Sopenharmony_ci } 11762306a36Sopenharmony_ci *tfm = tmp_tfm; 11862306a36Sopenharmony_ciunlock: 11962306a36Sopenharmony_ci mutex_unlock(&mutex); 12062306a36Sopenharmony_cialloc: 12162306a36Sopenharmony_ci desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm), 12262306a36Sopenharmony_ci GFP_KERNEL); 12362306a36Sopenharmony_ci if (!desc) 12462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci desc->tfm = *tfm; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci rc = crypto_shash_init(desc); 12962306a36Sopenharmony_ci if (rc) { 13062306a36Sopenharmony_ci kfree(desc); 13162306a36Sopenharmony_ci return ERR_PTR(rc); 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci return desc; 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci/* Protect against 'cutting & pasting' security.evm xattr, include inode 13762306a36Sopenharmony_ci * specific info. 13862306a36Sopenharmony_ci * 13962306a36Sopenharmony_ci * (Additional directory/file metadata needs to be added for more complete 14062306a36Sopenharmony_ci * protection.) 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_cistatic void hmac_add_misc(struct shash_desc *desc, struct inode *inode, 14362306a36Sopenharmony_ci char type, char *digest) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci struct h_misc { 14662306a36Sopenharmony_ci unsigned long ino; 14762306a36Sopenharmony_ci __u32 generation; 14862306a36Sopenharmony_ci uid_t uid; 14962306a36Sopenharmony_ci gid_t gid; 15062306a36Sopenharmony_ci umode_t mode; 15162306a36Sopenharmony_ci } hmac_misc; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci memset(&hmac_misc, 0, sizeof(hmac_misc)); 15462306a36Sopenharmony_ci /* Don't include the inode or generation number in portable 15562306a36Sopenharmony_ci * signatures 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_ci if (type != EVM_XATTR_PORTABLE_DIGSIG) { 15862306a36Sopenharmony_ci hmac_misc.ino = inode->i_ino; 15962306a36Sopenharmony_ci hmac_misc.generation = inode->i_generation; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci /* The hmac uid and gid must be encoded in the initial user 16262306a36Sopenharmony_ci * namespace (not the filesystems user namespace) as encoding 16362306a36Sopenharmony_ci * them in the filesystems user namespace allows an attack 16462306a36Sopenharmony_ci * where first they are written in an unprivileged fuse mount 16562306a36Sopenharmony_ci * of a filesystem and then the system is tricked to mount the 16662306a36Sopenharmony_ci * filesystem for real on next boot and trust it because 16762306a36Sopenharmony_ci * everything is signed. 16862306a36Sopenharmony_ci */ 16962306a36Sopenharmony_ci hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid); 17062306a36Sopenharmony_ci hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid); 17162306a36Sopenharmony_ci hmac_misc.mode = inode->i_mode; 17262306a36Sopenharmony_ci crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc)); 17362306a36Sopenharmony_ci if ((evm_hmac_attrs & EVM_ATTR_FSUUID) && 17462306a36Sopenharmony_ci type != EVM_XATTR_PORTABLE_DIGSIG) 17562306a36Sopenharmony_ci crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE); 17662306a36Sopenharmony_ci crypto_shash_final(desc, digest); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci pr_debug("hmac_misc: (%zu) [%*phN]\n", sizeof(struct h_misc), 17962306a36Sopenharmony_ci (int)sizeof(struct h_misc), &hmac_misc); 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/* 18362306a36Sopenharmony_ci * Dump large security xattr values as a continuous ascii hexademical string. 18462306a36Sopenharmony_ci * (pr_debug is limited to 64 bytes.) 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_cistatic void dump_security_xattr_l(const char *prefix, const void *src, 18762306a36Sopenharmony_ci size_t count) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) 19062306a36Sopenharmony_ci char *asciihex, *p; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci p = asciihex = kmalloc(count * 2 + 1, GFP_KERNEL); 19362306a36Sopenharmony_ci if (!asciihex) 19462306a36Sopenharmony_ci return; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci p = bin2hex(p, src, count); 19762306a36Sopenharmony_ci *p = 0; 19862306a36Sopenharmony_ci pr_debug("%s: (%zu) %.*s\n", prefix, count, (int)count * 2, asciihex); 19962306a36Sopenharmony_ci kfree(asciihex); 20062306a36Sopenharmony_ci#endif 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic void dump_security_xattr(const char *name, const char *value, 20462306a36Sopenharmony_ci size_t value_len) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci if (value_len < 64) 20762306a36Sopenharmony_ci pr_debug("%s: (%zu) [%*phN]\n", name, value_len, 20862306a36Sopenharmony_ci (int)value_len, value); 20962306a36Sopenharmony_ci else 21062306a36Sopenharmony_ci dump_security_xattr_l(name, value, value_len); 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci/* 21462306a36Sopenharmony_ci * Calculate the HMAC value across the set of protected security xattrs. 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * Instead of retrieving the requested xattr, for performance, calculate 21762306a36Sopenharmony_ci * the hmac using the requested xattr value. Don't alloc/free memory for 21862306a36Sopenharmony_ci * each xattr, but attempt to re-use the previously allocated memory. 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_cistatic int evm_calc_hmac_or_hash(struct dentry *dentry, 22162306a36Sopenharmony_ci const char *req_xattr_name, 22262306a36Sopenharmony_ci const char *req_xattr_value, 22362306a36Sopenharmony_ci size_t req_xattr_value_len, 22462306a36Sopenharmony_ci uint8_t type, struct evm_digest *data) 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci struct inode *inode = d_backing_inode(dentry); 22762306a36Sopenharmony_ci struct xattr_list *xattr; 22862306a36Sopenharmony_ci struct shash_desc *desc; 22962306a36Sopenharmony_ci size_t xattr_size = 0; 23062306a36Sopenharmony_ci char *xattr_value = NULL; 23162306a36Sopenharmony_ci int error; 23262306a36Sopenharmony_ci int size, user_space_size; 23362306a36Sopenharmony_ci bool ima_present = false; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci if (!(inode->i_opflags & IOP_XATTR) || 23662306a36Sopenharmony_ci inode->i_sb->s_user_ns != &init_user_ns) 23762306a36Sopenharmony_ci return -EOPNOTSUPP; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci desc = init_desc(type, data->hdr.algo); 24062306a36Sopenharmony_ci if (IS_ERR(desc)) 24162306a36Sopenharmony_ci return PTR_ERR(desc); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci data->hdr.length = crypto_shash_digestsize(desc->tfm); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci error = -ENODATA; 24662306a36Sopenharmony_ci list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) { 24762306a36Sopenharmony_ci bool is_ima = false; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci if (strcmp(xattr->name, XATTR_NAME_IMA) == 0) 25062306a36Sopenharmony_ci is_ima = true; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci /* 25362306a36Sopenharmony_ci * Skip non-enabled xattrs for locally calculated 25462306a36Sopenharmony_ci * signatures/HMACs. 25562306a36Sopenharmony_ci */ 25662306a36Sopenharmony_ci if (type != EVM_XATTR_PORTABLE_DIGSIG && !xattr->enabled) 25762306a36Sopenharmony_ci continue; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if ((req_xattr_name && req_xattr_value) 26062306a36Sopenharmony_ci && !strcmp(xattr->name, req_xattr_name)) { 26162306a36Sopenharmony_ci error = 0; 26262306a36Sopenharmony_ci crypto_shash_update(desc, (const u8 *)req_xattr_value, 26362306a36Sopenharmony_ci req_xattr_value_len); 26462306a36Sopenharmony_ci if (is_ima) 26562306a36Sopenharmony_ci ima_present = true; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci dump_security_xattr(req_xattr_name, 26862306a36Sopenharmony_ci req_xattr_value, 26962306a36Sopenharmony_ci req_xattr_value_len); 27062306a36Sopenharmony_ci continue; 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci size = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, xattr->name, 27362306a36Sopenharmony_ci &xattr_value, xattr_size, GFP_NOFS); 27462306a36Sopenharmony_ci if (size == -ENOMEM) { 27562306a36Sopenharmony_ci error = -ENOMEM; 27662306a36Sopenharmony_ci goto out; 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci if (size < 0) 27962306a36Sopenharmony_ci continue; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci user_space_size = vfs_getxattr(&nop_mnt_idmap, dentry, 28262306a36Sopenharmony_ci xattr->name, NULL, 0); 28362306a36Sopenharmony_ci if (user_space_size != size) 28462306a36Sopenharmony_ci pr_debug("file %s: xattr %s size mismatch (kernel: %d, user: %d)\n", 28562306a36Sopenharmony_ci dentry->d_name.name, xattr->name, size, 28662306a36Sopenharmony_ci user_space_size); 28762306a36Sopenharmony_ci error = 0; 28862306a36Sopenharmony_ci xattr_size = size; 28962306a36Sopenharmony_ci crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size); 29062306a36Sopenharmony_ci if (is_ima) 29162306a36Sopenharmony_ci ima_present = true; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci dump_security_xattr(xattr->name, xattr_value, xattr_size); 29462306a36Sopenharmony_ci } 29562306a36Sopenharmony_ci hmac_add_misc(desc, inode, type, data->digest); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* Portable EVM signatures must include an IMA hash */ 29862306a36Sopenharmony_ci if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present) 29962306a36Sopenharmony_ci error = -EPERM; 30062306a36Sopenharmony_ciout: 30162306a36Sopenharmony_ci kfree(xattr_value); 30262306a36Sopenharmony_ci kfree(desc); 30362306a36Sopenharmony_ci return error; 30462306a36Sopenharmony_ci} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ciint evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, 30762306a36Sopenharmony_ci const char *req_xattr_value, size_t req_xattr_value_len, 30862306a36Sopenharmony_ci struct evm_digest *data) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, 31162306a36Sopenharmony_ci req_xattr_value_len, EVM_XATTR_HMAC, data); 31262306a36Sopenharmony_ci} 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ciint evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, 31562306a36Sopenharmony_ci const char *req_xattr_value, size_t req_xattr_value_len, 31662306a36Sopenharmony_ci char type, struct evm_digest *data) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, 31962306a36Sopenharmony_ci req_xattr_value_len, type, data); 32062306a36Sopenharmony_ci} 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cistatic int evm_is_immutable(struct dentry *dentry, struct inode *inode) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci const struct evm_ima_xattr_data *xattr_data = NULL; 32562306a36Sopenharmony_ci struct integrity_iint_cache *iint; 32662306a36Sopenharmony_ci int rc = 0; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci iint = integrity_iint_find(inode); 32962306a36Sopenharmony_ci if (iint && (iint->flags & EVM_IMMUTABLE_DIGSIG)) 33062306a36Sopenharmony_ci return 1; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci /* Do this the hard way */ 33362306a36Sopenharmony_ci rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM, 33462306a36Sopenharmony_ci (char **)&xattr_data, 0, GFP_NOFS); 33562306a36Sopenharmony_ci if (rc <= 0) { 33662306a36Sopenharmony_ci if (rc == -ENODATA) 33762306a36Sopenharmony_ci rc = 0; 33862306a36Sopenharmony_ci goto out; 33962306a36Sopenharmony_ci } 34062306a36Sopenharmony_ci if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) 34162306a36Sopenharmony_ci rc = 1; 34262306a36Sopenharmony_ci else 34362306a36Sopenharmony_ci rc = 0; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ciout: 34662306a36Sopenharmony_ci kfree(xattr_data); 34762306a36Sopenharmony_ci return rc; 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci/* 35262306a36Sopenharmony_ci * Calculate the hmac and update security.evm xattr 35362306a36Sopenharmony_ci * 35462306a36Sopenharmony_ci * Expects to be called with i_mutex locked. 35562306a36Sopenharmony_ci */ 35662306a36Sopenharmony_ciint evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, 35762306a36Sopenharmony_ci const char *xattr_value, size_t xattr_value_len) 35862306a36Sopenharmony_ci{ 35962306a36Sopenharmony_ci struct inode *inode = d_backing_inode(dentry); 36062306a36Sopenharmony_ci struct evm_digest data; 36162306a36Sopenharmony_ci int rc = 0; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci /* 36462306a36Sopenharmony_ci * Don't permit any transformation of the EVM xattr if the signature 36562306a36Sopenharmony_ci * is of an immutable type 36662306a36Sopenharmony_ci */ 36762306a36Sopenharmony_ci rc = evm_is_immutable(dentry, inode); 36862306a36Sopenharmony_ci if (rc < 0) 36962306a36Sopenharmony_ci return rc; 37062306a36Sopenharmony_ci if (rc) 37162306a36Sopenharmony_ci return -EPERM; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci data.hdr.algo = HASH_ALGO_SHA1; 37462306a36Sopenharmony_ci rc = evm_calc_hmac(dentry, xattr_name, xattr_value, 37562306a36Sopenharmony_ci xattr_value_len, &data); 37662306a36Sopenharmony_ci if (rc == 0) { 37762306a36Sopenharmony_ci data.hdr.xattr.sha1.type = EVM_XATTR_HMAC; 37862306a36Sopenharmony_ci rc = __vfs_setxattr_noperm(&nop_mnt_idmap, dentry, 37962306a36Sopenharmony_ci XATTR_NAME_EVM, 38062306a36Sopenharmony_ci &data.hdr.xattr.data[1], 38162306a36Sopenharmony_ci SHA1_DIGEST_SIZE + 1, 0); 38262306a36Sopenharmony_ci } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) { 38362306a36Sopenharmony_ci rc = __vfs_removexattr(&nop_mnt_idmap, dentry, XATTR_NAME_EVM); 38462306a36Sopenharmony_ci } 38562306a36Sopenharmony_ci return rc; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ciint evm_init_hmac(struct inode *inode, const struct xattr *xattrs, 38962306a36Sopenharmony_ci char *hmac_val) 39062306a36Sopenharmony_ci{ 39162306a36Sopenharmony_ci struct shash_desc *desc; 39262306a36Sopenharmony_ci const struct xattr *xattr; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1); 39562306a36Sopenharmony_ci if (IS_ERR(desc)) { 39662306a36Sopenharmony_ci pr_info("init_desc failed\n"); 39762306a36Sopenharmony_ci return PTR_ERR(desc); 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci for (xattr = xattrs; xattr->name; xattr++) { 40162306a36Sopenharmony_ci if (!evm_protected_xattr(xattr->name)) 40262306a36Sopenharmony_ci continue; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci crypto_shash_update(desc, xattr->value, xattr->value_len); 40562306a36Sopenharmony_ci } 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci hmac_add_misc(desc, inode, EVM_XATTR_HMAC, hmac_val); 40862306a36Sopenharmony_ci kfree(desc); 40962306a36Sopenharmony_ci return 0; 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci/* 41362306a36Sopenharmony_ci * Get the key from the TPM for the SHA1-HMAC 41462306a36Sopenharmony_ci */ 41562306a36Sopenharmony_ciint evm_init_key(void) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci struct key *evm_key; 41862306a36Sopenharmony_ci struct encrypted_key_payload *ekp; 41962306a36Sopenharmony_ci int rc; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci evm_key = request_key(&key_type_encrypted, EVMKEY, NULL); 42262306a36Sopenharmony_ci if (IS_ERR(evm_key)) 42362306a36Sopenharmony_ci return -ENOENT; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci down_read(&evm_key->sem); 42662306a36Sopenharmony_ci ekp = evm_key->payload.data[0]; 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci rc = evm_set_key(ekp->decrypted_data, ekp->decrypted_datalen); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /* burn the original key contents */ 43162306a36Sopenharmony_ci memset(ekp->decrypted_data, 0, ekp->decrypted_datalen); 43262306a36Sopenharmony_ci up_read(&evm_key->sem); 43362306a36Sopenharmony_ci key_put(evm_key); 43462306a36Sopenharmony_ci return rc; 43562306a36Sopenharmony_ci} 436