diff options
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/evm/evm.h | 3 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 20 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 38 |
3 files changed, 61 insertions, 0 deletions
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index 375dc3e6015c..a45d0d630a30 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h | |||
@@ -12,6 +12,7 @@ | |||
12 | * File: evm.h | 12 | * File: evm.h |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | #include <linux/xattr.h> | ||
15 | #include <linux/security.h> | 16 | #include <linux/security.h> |
16 | #include "../integrity.h" | 17 | #include "../integrity.h" |
17 | 18 | ||
@@ -29,5 +30,7 @@ extern int evm_update_evmxattr(struct dentry *dentry, | |||
29 | extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | 30 | extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, |
30 | const char *req_xattr_value, | 31 | const char *req_xattr_value, |
31 | size_t req_xattr_value_len, char *digest); | 32 | size_t req_xattr_value_len, char *digest); |
33 | extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr, | ||
34 | char *hmac_val); | ||
32 | extern int evm_init_secfs(void); | 35 | extern int evm_init_secfs(void); |
33 | extern void evm_cleanup_secfs(void); | 36 | extern void evm_cleanup_secfs(void); |
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index c631b99bda95..c9902bddcb9a 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
@@ -157,6 +157,26 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, | |||
157 | return rc; | 157 | return rc; |
158 | } | 158 | } |
159 | 159 | ||
160 | int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr, | ||
161 | char *hmac_val) | ||
162 | { | ||
163 | struct hash_desc desc; | ||
164 | struct scatterlist sg[1]; | ||
165 | int error; | ||
166 | |||
167 | error = init_desc(&desc); | ||
168 | if (error != 0) { | ||
169 | printk(KERN_INFO "init_desc failed\n"); | ||
170 | return error; | ||
171 | } | ||
172 | |||
173 | sg_init_one(sg, lsm_xattr->value, lsm_xattr->value_len); | ||
174 | crypto_hash_update(&desc, sg, lsm_xattr->value_len); | ||
175 | hmac_add_misc(&desc, inode, hmac_val); | ||
176 | crypto_free_hash(desc.tfm); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
160 | /* | 180 | /* |
161 | * Get the key from the TPM for the SHA1-HMAC | 181 | * Get the key from the TPM for the SHA1-HMAC |
162 | */ | 182 | */ |
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 1746c3669c6f..23486355f443 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
@@ -98,6 +98,12 @@ static int evm_protected_xattr(const char *req_xattr_name) | |||
98 | found = 1; | 98 | found = 1; |
99 | break; | 99 | break; |
100 | } | 100 | } |
101 | if (strncmp(req_xattr_name, | ||
102 | *xattrname + XATTR_SECURITY_PREFIX_LEN, | ||
103 | strlen(req_xattr_name)) == 0) { | ||
104 | found = 1; | ||
105 | break; | ||
106 | } | ||
101 | } | 107 | } |
102 | return found; | 108 | return found; |
103 | } | 109 | } |
@@ -245,6 +251,38 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid) | |||
245 | return; | 251 | return; |
246 | } | 252 | } |
247 | 253 | ||
254 | /* | ||
255 | * evm_inode_init_security - initializes security.evm | ||
256 | */ | ||
257 | int evm_inode_init_security(struct inode *inode, | ||
258 | const struct xattr *lsm_xattr, | ||
259 | struct xattr *evm_xattr) | ||
260 | { | ||
261 | struct evm_ima_xattr_data *xattr_data; | ||
262 | int rc; | ||
263 | |||
264 | if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name)) | ||
265 | return -EOPNOTSUPP; | ||
266 | |||
267 | xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS); | ||
268 | if (!xattr_data) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | xattr_data->type = EVM_XATTR_HMAC; | ||
272 | rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest); | ||
273 | if (rc < 0) | ||
274 | goto out; | ||
275 | |||
276 | evm_xattr->value = xattr_data; | ||
277 | evm_xattr->value_len = sizeof(*xattr_data); | ||
278 | evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS); | ||
279 | return 0; | ||
280 | out: | ||
281 | kfree(xattr_data); | ||
282 | return rc; | ||
283 | } | ||
284 | EXPORT_SYMBOL_GPL(evm_inode_init_security); | ||
285 | |||
248 | static struct crypto_hash *tfm_hmac; /* preload crypto alg */ | 286 | static struct crypto_hash *tfm_hmac; /* preload crypto alg */ |
249 | static int __init init_evm(void) | 287 | static int __init init_evm(void) |
250 | { | 288 | { |