diff options
Diffstat (limited to 'security/integrity/evm/evm_crypto.c')
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 5dd5b140242c..847a2d7dff17 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
@@ -26,34 +26,48 @@ static unsigned char evmkey[MAX_KEY_SIZE]; | |||
26 | static int evmkey_len = MAX_KEY_SIZE; | 26 | static int evmkey_len = MAX_KEY_SIZE; |
27 | 27 | ||
28 | struct crypto_shash *hmac_tfm; | 28 | struct crypto_shash *hmac_tfm; |
29 | struct crypto_shash *hash_tfm; | ||
29 | 30 | ||
30 | static struct shash_desc *init_desc(void) | 31 | static struct shash_desc *init_desc(const char type) |
31 | { | 32 | { |
32 | int rc; | 33 | int rc; |
34 | char *algo; | ||
35 | struct crypto_shash **tfm; | ||
33 | struct shash_desc *desc; | 36 | struct shash_desc *desc; |
34 | 37 | ||
35 | if (hmac_tfm == NULL) { | 38 | if (type == EVM_XATTR_HMAC) { |
36 | hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC); | 39 | tfm = &hmac_tfm; |
37 | if (IS_ERR(hmac_tfm)) { | 40 | algo = evm_hmac; |
41 | } else { | ||
42 | tfm = &hash_tfm; | ||
43 | algo = evm_hash; | ||
44 | } | ||
45 | |||
46 | if (*tfm == NULL) { | ||
47 | *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC); | ||
48 | if (IS_ERR(*tfm)) { | ||
38 | pr_err("Can not allocate %s (reason: %ld)\n", | 49 | pr_err("Can not allocate %s (reason: %ld)\n", |
39 | evm_hmac, PTR_ERR(hmac_tfm)); | 50 | algo, PTR_ERR(*tfm)); |
40 | rc = PTR_ERR(hmac_tfm); | 51 | rc = PTR_ERR(*tfm); |
41 | hmac_tfm = NULL; | 52 | *tfm = NULL; |
42 | return ERR_PTR(rc); | 53 | return ERR_PTR(rc); |
43 | } | 54 | } |
44 | } | 55 | } |
45 | 56 | ||
46 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm), | 57 | desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm), |
47 | GFP_KERNEL); | 58 | GFP_KERNEL); |
48 | if (!desc) | 59 | if (!desc) |
49 | return ERR_PTR(-ENOMEM); | 60 | return ERR_PTR(-ENOMEM); |
50 | 61 | ||
51 | desc->tfm = hmac_tfm; | 62 | desc->tfm = *tfm; |
52 | desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 63 | desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
53 | 64 | ||
54 | rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len); | 65 | if (type == EVM_XATTR_HMAC) { |
55 | if (rc) | 66 | rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len); |
56 | goto out; | 67 | if (rc) |
68 | goto out; | ||
69 | } | ||
70 | |||
57 | rc = crypto_shash_init(desc); | 71 | rc = crypto_shash_init(desc); |
58 | out: | 72 | out: |
59 | if (rc) { | 73 | if (rc) { |
@@ -97,9 +111,11 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode, | |||
97 | * the hmac using the requested xattr value. Don't alloc/free memory for | 111 | * the hmac using the requested xattr value. Don't alloc/free memory for |
98 | * each xattr, but attempt to re-use the previously allocated memory. | 112 | * each xattr, but attempt to re-use the previously allocated memory. |
99 | */ | 113 | */ |
100 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | 114 | static int evm_calc_hmac_or_hash(struct dentry *dentry, |
101 | const char *req_xattr_value, size_t req_xattr_value_len, | 115 | const char *req_xattr_name, |
102 | char *digest) | 116 | const char *req_xattr_value, |
117 | size_t req_xattr_value_len, | ||
118 | char type, char *digest) | ||
103 | { | 119 | { |
104 | struct inode *inode = dentry->d_inode; | 120 | struct inode *inode = dentry->d_inode; |
105 | struct shash_desc *desc; | 121 | struct shash_desc *desc; |
@@ -111,7 +127,7 @@ int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | |||
111 | 127 | ||
112 | if (!inode->i_op || !inode->i_op->getxattr) | 128 | if (!inode->i_op || !inode->i_op->getxattr) |
113 | return -EOPNOTSUPP; | 129 | return -EOPNOTSUPP; |
114 | desc = init_desc(); | 130 | desc = init_desc(type); |
115 | if (IS_ERR(desc)) | 131 | if (IS_ERR(desc)) |
116 | return PTR_ERR(desc); | 132 | return PTR_ERR(desc); |
117 | 133 | ||
@@ -145,6 +161,22 @@ out: | |||
145 | return error; | 161 | return error; |
146 | } | 162 | } |
147 | 163 | ||
164 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | ||
165 | const char *req_xattr_value, size_t req_xattr_value_len, | ||
166 | char *digest) | ||
167 | { | ||
168 | return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, | ||
169 | req_xattr_value_len, EVM_XATTR_HMAC, digest); | ||
170 | } | ||
171 | |||
172 | int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, | ||
173 | const char *req_xattr_value, size_t req_xattr_value_len, | ||
174 | char *digest) | ||
175 | { | ||
176 | return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, | ||
177 | req_xattr_value_len, IMA_XATTR_DIGEST, digest); | ||
178 | } | ||
179 | |||
148 | /* | 180 | /* |
149 | * Calculate the hmac and update security.evm xattr | 181 | * Calculate the hmac and update security.evm xattr |
150 | * | 182 | * |
@@ -175,7 +207,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr, | |||
175 | { | 207 | { |
176 | struct shash_desc *desc; | 208 | struct shash_desc *desc; |
177 | 209 | ||
178 | desc = init_desc(); | 210 | desc = init_desc(EVM_XATTR_HMAC); |
179 | if (IS_ERR(desc)) { | 211 | if (IS_ERR(desc)) { |
180 | printk(KERN_INFO "init_desc failed\n"); | 212 | printk(KERN_INFO "init_desc failed\n"); |
181 | return PTR_ERR(desc); | 213 | return PTR_ERR(desc); |