Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 264487
b: refs/heads/master
c: d46eb36
h: refs/heads/master
i:
  264485: 23aaf2d
  264483: e61f3e4
  264479: db9f3de
v: v3
  • Loading branch information
Dmitry Kasatkin authored and Mimi Zohar committed Jul 18, 2011
1 parent 9622958 commit d8d0211
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 823eb1ccd0b310449e99c822412ea8208334d14c
refs/heads/master: d46eb3699502ba221e81e88e6c6594e2a7818532
2 changes: 2 additions & 0 deletions trunk/security/integrity/evm/evm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
extern int evm_initialized;
extern char *evm_hmac;

extern struct crypto_shash *hmac_tfm;

/* List of EVM protected security xattrs */
extern char *evm_config_xattrnames[];

Expand Down
94 changes: 52 additions & 42 deletions trunk/security/integrity/evm/evm_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,51 @@
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/xattr.h>
#include <linux/scatterlist.h>
#include <keys/encrypted-type.h>
#include <crypto/hash.h>
#include "evm.h"

#define EVMKEY "evm-key"
#define MAX_KEY_SIZE 128
static unsigned char evmkey[MAX_KEY_SIZE];
static int evmkey_len = MAX_KEY_SIZE;

static int init_desc(struct hash_desc *desc)
struct crypto_shash *hmac_tfm;

static struct shash_desc *init_desc(void)
{
int rc;

desc->tfm = crypto_alloc_hash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(desc->tfm)) {
pr_info("Can not allocate %s (reason: %ld)\n",
evm_hmac, PTR_ERR(desc->tfm));
rc = PTR_ERR(desc->tfm);
return rc;
struct shash_desc *desc;

if (hmac_tfm == NULL) {
hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(hmac_tfm)) {
pr_err("Can not allocate %s (reason: %ld)\n",
evm_hmac, PTR_ERR(hmac_tfm));
rc = PTR_ERR(hmac_tfm);
hmac_tfm = NULL;
return ERR_PTR(rc);
}
}
desc->flags = 0;
rc = crypto_hash_setkey(desc->tfm, evmkey, evmkey_len);

desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm),
GFP_KERNEL);
if (!desc)
return ERR_PTR(-ENOMEM);

desc->tfm = hmac_tfm;
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;

rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len);
if (rc)
goto out;
rc = crypto_hash_init(desc);
rc = crypto_shash_init(desc);
out:
if (rc)
crypto_free_hash(desc->tfm);
return rc;
if (rc) {
kfree(desc);
return ERR_PTR(rc);
}
return desc;
}

/* Protect against 'cutting & pasting' security.evm xattr, include inode
Expand All @@ -53,7 +69,7 @@ static int init_desc(struct hash_desc *desc)
* (Additional directory/file metadata needs to be added for more complete
* protection.)
*/
static void hmac_add_misc(struct hash_desc *desc, struct inode *inode,
static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
char *digest)
{
struct h_misc {
Expand All @@ -63,17 +79,15 @@ static void hmac_add_misc(struct hash_desc *desc, struct inode *inode,
gid_t gid;
umode_t mode;
} hmac_misc;
struct scatterlist sg[1];

memset(&hmac_misc, 0, sizeof hmac_misc);
hmac_misc.ino = inode->i_ino;
hmac_misc.generation = inode->i_generation;
hmac_misc.uid = inode->i_uid;
hmac_misc.gid = inode->i_gid;
hmac_misc.mode = inode->i_mode;
sg_init_one(sg, &hmac_misc, sizeof hmac_misc);
crypto_hash_update(desc, sg, sizeof hmac_misc);
crypto_hash_final(desc, digest);
crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
crypto_shash_final(desc, digest);
}

/*
Expand All @@ -88,8 +102,7 @@ int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
char *digest)
{
struct inode *inode = dentry->d_inode;
struct hash_desc desc;
struct scatterlist sg[1];
struct shash_desc *desc;
char **xattrname;
size_t xattr_size = 0;
char *xattr_value = NULL;
Expand All @@ -98,17 +111,17 @@ int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,

if (!inode->i_op || !inode->i_op->getxattr)
return -EOPNOTSUPP;
error = init_desc(&desc);
if (error)
return error;
desc = init_desc();
if (IS_ERR(desc))
return PTR_ERR(desc);

error = -ENODATA;
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
if ((req_xattr_name && req_xattr_value)
&& !strcmp(*xattrname, req_xattr_name)) {
error = 0;
sg_init_one(sg, req_xattr_value, req_xattr_value_len);
crypto_hash_update(&desc, sg, req_xattr_value_len);
crypto_shash_update(desc, (const u8 *)req_xattr_value,
req_xattr_value_len);
continue;
}
size = vfs_getxattr_alloc(dentry, *xattrname,
Expand All @@ -122,13 +135,13 @@ int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,

error = 0;
xattr_size = size;
sg_init_one(sg, xattr_value, xattr_size);
crypto_hash_update(&desc, sg, xattr_size);
crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
}
hmac_add_misc(&desc, inode, digest);
kfree(xattr_value);
hmac_add_misc(desc, inode, digest);

out:
crypto_free_hash(desc.tfm);
kfree(xattr_value);
kfree(desc);
return error;
}

Expand Down Expand Up @@ -160,20 +173,17 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
char *hmac_val)
{
struct hash_desc desc;
struct scatterlist sg[1];
int error;
struct shash_desc *desc;

error = init_desc(&desc);
if (error != 0) {
desc = init_desc();
if (IS_ERR(desc)) {
printk(KERN_INFO "init_desc failed\n");
return error;
return PTR_ERR(desc);
}

sg_init_one(sg, lsm_xattr->value, lsm_xattr->value_len);
crypto_hash_update(&desc, sg, lsm_xattr->value_len);
hmac_add_misc(&desc, inode, hmac_val);
crypto_free_hash(desc.tfm);
crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
hmac_add_misc(desc, inode, hmac_val);
kfree(desc);
return 0;
}

Expand Down
6 changes: 3 additions & 3 deletions trunk/security/integrity/evm/evm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/xattr.h>
#include <linux/integrity.h>
#include <linux/evm.h>
#include <crypto/hash.h>
#include "evm.h"

int evm_initialized;
Expand Down Expand Up @@ -283,12 +284,10 @@ int evm_inode_init_security(struct inode *inode,
}
EXPORT_SYMBOL_GPL(evm_inode_init_security);

static struct crypto_hash *tfm_hmac; /* preload crypto alg */
static int __init init_evm(void)
{
int error;

tfm_hmac = crypto_alloc_hash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
error = evm_init_secfs();
if (error < 0) {
printk(KERN_INFO "EVM: Error registering secfs\n");
Expand All @@ -301,7 +300,8 @@ static int __init init_evm(void)
static void __exit cleanup_evm(void)
{
evm_cleanup_secfs();
crypto_free_hash(tfm_hmac);
if (hmac_tfm)
crypto_free_shash(hmac_tfm);
}

/*
Expand Down

0 comments on commit d8d0211

Please sign in to comment.