aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/evm/evm_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/evm/evm_crypto.c')
-rw-r--r--security/integrity/evm/evm_crypto.c76
1 files changed, 53 insertions, 23 deletions
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 8738deff26fa..49a464f5595b 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -26,44 +26,56 @@ static unsigned char evmkey[MAX_KEY_SIZE];
26static int evmkey_len = MAX_KEY_SIZE; 26static int evmkey_len = MAX_KEY_SIZE;
27 27
28struct crypto_shash *hmac_tfm; 28struct crypto_shash *hmac_tfm;
29struct crypto_shash *hash_tfm;
29 30
30static DEFINE_MUTEX(mutex); 31static DEFINE_MUTEX(mutex);
31 32
32static struct shash_desc *init_desc(void) 33static struct shash_desc *init_desc(char type)
33{ 34{
34 int rc; 35 long rc;
36 char *algo;
37 struct crypto_shash **tfm;
35 struct shash_desc *desc; 38 struct shash_desc *desc;
36 39
37 if (hmac_tfm == NULL) { 40 if (type == EVM_XATTR_HMAC) {
41 tfm = &hmac_tfm;
42 algo = evm_hmac;
43 } else {
44 tfm = &hash_tfm;
45 algo = evm_hash;
46 }
47
48 if (*tfm == NULL) {
38 mutex_lock(&mutex); 49 mutex_lock(&mutex);
39 if (hmac_tfm) 50 if (*tfm)
40 goto out; 51 goto out;
41 hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC); 52 *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
42 if (IS_ERR(hmac_tfm)) { 53 if (IS_ERR(*tfm)) {
43 pr_err("Can not allocate %s (reason: %ld)\n", 54 rc = PTR_ERR(*tfm);
44 evm_hmac, PTR_ERR(hmac_tfm)); 55 pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
45 rc = PTR_ERR(hmac_tfm); 56 *tfm = NULL;
46 hmac_tfm = NULL;
47 mutex_unlock(&mutex); 57 mutex_unlock(&mutex);
48 return ERR_PTR(rc); 58 return ERR_PTR(rc);
49 } 59 }
50 rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len); 60 if (type == EVM_XATTR_HMAC) {
51 if (rc) { 61 rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len);
52 crypto_free_shash(hmac_tfm); 62 if (rc) {
53 hmac_tfm = NULL; 63 crypto_free_shash(*tfm);
54 mutex_unlock(&mutex); 64 *tfm = NULL;
55 return ERR_PTR(rc); 65 mutex_unlock(&mutex);
66 return ERR_PTR(rc);
67 }
56 } 68 }
57out: 69out:
58 mutex_unlock(&mutex); 70 mutex_unlock(&mutex);
59 } 71 }
60 72
61 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm), 73 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),
62 GFP_KERNEL); 74 GFP_KERNEL);
63 if (!desc) 75 if (!desc)
64 return ERR_PTR(-ENOMEM); 76 return ERR_PTR(-ENOMEM);
65 77
66 desc->tfm = hmac_tfm; 78 desc->tfm = *tfm;
67 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 79 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
68 80
69 rc = crypto_shash_init(desc); 81 rc = crypto_shash_init(desc);
@@ -108,9 +120,11 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
108 * the hmac using the requested xattr value. Don't alloc/free memory for 120 * the hmac using the requested xattr value. Don't alloc/free memory for
109 * each xattr, but attempt to re-use the previously allocated memory. 121 * each xattr, but attempt to re-use the previously allocated memory.
110 */ 122 */
111int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, 123static int evm_calc_hmac_or_hash(struct dentry *dentry,
112 const char *req_xattr_value, size_t req_xattr_value_len, 124 const char *req_xattr_name,
113 char *digest) 125 const char *req_xattr_value,
126 size_t req_xattr_value_len,
127 char type, char *digest)
114{ 128{
115 struct inode *inode = dentry->d_inode; 129 struct inode *inode = dentry->d_inode;
116 struct shash_desc *desc; 130 struct shash_desc *desc;
@@ -122,7 +136,7 @@ int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
122 136
123 if (!inode->i_op || !inode->i_op->getxattr) 137 if (!inode->i_op || !inode->i_op->getxattr)
124 return -EOPNOTSUPP; 138 return -EOPNOTSUPP;
125 desc = init_desc(); 139 desc = init_desc(type);
126 if (IS_ERR(desc)) 140 if (IS_ERR(desc))
127 return PTR_ERR(desc); 141 return PTR_ERR(desc);
128 142
@@ -156,6 +170,22 @@ out:
156 return error; 170 return error;
157} 171}
158 172
173int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
174 const char *req_xattr_value, size_t req_xattr_value_len,
175 char *digest)
176{
177 return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
178 req_xattr_value_len, EVM_XATTR_HMAC, digest);
179}
180
181int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
182 const char *req_xattr_value, size_t req_xattr_value_len,
183 char *digest)
184{
185 return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
186 req_xattr_value_len, IMA_XATTR_DIGEST, digest);
187}
188
159/* 189/*
160 * Calculate the hmac and update security.evm xattr 190 * Calculate the hmac and update security.evm xattr
161 * 191 *
@@ -186,7 +216,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
186{ 216{
187 struct shash_desc *desc; 217 struct shash_desc *desc;
188 218
189 desc = init_desc(); 219 desc = init_desc(EVM_XATTR_HMAC);
190 if (IS_ERR(desc)) { 220 if (IS_ERR(desc)) {
191 printk(KERN_INFO "init_desc failed\n"); 221 printk(KERN_INFO "init_desc failed\n");
192 return PTR_ERR(desc); 222 return PTR_ERR(desc);