diff options
Diffstat (limited to 'security/integrity/evm/evm_crypto.c')
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 76 |
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]; | |||
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 DEFINE_MUTEX(mutex); | 31 | static DEFINE_MUTEX(mutex); |
31 | 32 | ||
32 | static struct shash_desc *init_desc(void) | 33 | static 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 | } |
57 | out: | 69 | out: |
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 | */ |
111 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | 123 | static 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 | ||
173 | int 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 | |||
181 | int 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); |