diff options
author | Dmitry Kasatkin <d.kasatkin@samsung.com> | 2013-04-25 03:43:56 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2013-10-25 17:16:58 -0400 |
commit | c7c8bb237fdbff932b5e431aebee5ce862ea07d1 (patch) | |
tree | 4cdbc7c250dd4418b47ab45dd1108848b50f8cff /security/integrity/ima/ima_crypto.c | |
parent | 3fe78ca2fb1d61ea598e63fcbf38aec76b36b3a8 (diff) |
ima: provide support for arbitrary hash algorithms
In preparation of supporting more hash algorithms with larger hash sizes
needed for signature verification, this patch replaces the 20 byte sized
digest, with a more flexible structure. The new structure includes the
hash algorithm, digest size, and digest.
Changelog:
- recalculate filedata hash for the measurement list, if the signature
hash digest size is greater than 20 bytes.
- use generic HASH_ALGO_
- make ima_calc_file_hash static
- scripts lindent and checkpatch fixes
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity/ima/ima_crypto.c')
-rw-r--r-- | security/integrity/ima/ima_crypto.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index a02e0791cf15..2fd178651467 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <crypto/hash.h> | 22 | #include <crypto/hash.h> |
23 | #include <crypto/hash_info.h> | ||
23 | #include "ima.h" | 24 | #include "ima.h" |
24 | 25 | ||
25 | static struct crypto_shash *ima_shash_tfm; | 26 | static struct crypto_shash *ima_shash_tfm; |
@@ -28,10 +29,11 @@ int ima_init_crypto(void) | |||
28 | { | 29 | { |
29 | long rc; | 30 | long rc; |
30 | 31 | ||
31 | ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0); | 32 | ima_shash_tfm = crypto_alloc_shash(hash_algo_name[ima_hash_algo], 0, 0); |
32 | if (IS_ERR(ima_shash_tfm)) { | 33 | if (IS_ERR(ima_shash_tfm)) { |
33 | rc = PTR_ERR(ima_shash_tfm); | 34 | rc = PTR_ERR(ima_shash_tfm); |
34 | pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc); | 35 | pr_err("Can not allocate %s (reason: %ld)\n", |
36 | hash_algo_name[ima_hash_algo], rc); | ||
35 | return rc; | 37 | return rc; |
36 | } | 38 | } |
37 | return 0; | 39 | return 0; |
@@ -40,17 +42,19 @@ int ima_init_crypto(void) | |||
40 | /* | 42 | /* |
41 | * Calculate the MD5/SHA1 file digest | 43 | * Calculate the MD5/SHA1 file digest |
42 | */ | 44 | */ |
43 | int ima_calc_file_hash(struct file *file, char *digest) | 45 | static int ima_calc_file_hash_tfm(struct file *file, |
46 | struct ima_digest_data *hash, | ||
47 | struct crypto_shash *tfm) | ||
44 | { | 48 | { |
45 | loff_t i_size, offset = 0; | 49 | loff_t i_size, offset = 0; |
46 | char *rbuf; | 50 | char *rbuf; |
47 | int rc, read = 0; | 51 | int rc, read = 0; |
48 | struct { | 52 | struct { |
49 | struct shash_desc shash; | 53 | struct shash_desc shash; |
50 | char ctx[crypto_shash_descsize(ima_shash_tfm)]; | 54 | char ctx[crypto_shash_descsize(tfm)]; |
51 | } desc; | 55 | } desc; |
52 | 56 | ||
53 | desc.shash.tfm = ima_shash_tfm; | 57 | desc.shash.tfm = tfm; |
54 | desc.shash.flags = 0; | 58 | desc.shash.flags = 0; |
55 | 59 | ||
56 | rc = crypto_shash_init(&desc.shash); | 60 | rc = crypto_shash_init(&desc.shash); |
@@ -85,17 +89,42 @@ int ima_calc_file_hash(struct file *file, char *digest) | |||
85 | } | 89 | } |
86 | kfree(rbuf); | 90 | kfree(rbuf); |
87 | if (!rc) | 91 | if (!rc) |
88 | rc = crypto_shash_final(&desc.shash, digest); | 92 | rc = crypto_shash_final(&desc.shash, hash->digest); |
89 | if (read) | 93 | if (read) |
90 | file->f_mode &= ~FMODE_READ; | 94 | file->f_mode &= ~FMODE_READ; |
91 | out: | 95 | out: |
92 | return rc; | 96 | return rc; |
93 | } | 97 | } |
94 | 98 | ||
99 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash) | ||
100 | { | ||
101 | struct crypto_shash *tfm = ima_shash_tfm; | ||
102 | int rc; | ||
103 | |||
104 | if (hash->algo != ima_hash_algo && hash->algo < HASH_ALGO__LAST) { | ||
105 | tfm = crypto_alloc_shash(hash_algo_name[hash->algo], 0, 0); | ||
106 | if (IS_ERR(tfm)) { | ||
107 | rc = PTR_ERR(tfm); | ||
108 | pr_err("Can not allocate %s (reason: %d)\n", | ||
109 | hash_algo_name[hash->algo], rc); | ||
110 | return rc; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | hash->length = crypto_shash_digestsize(tfm); | ||
115 | |||
116 | rc = ima_calc_file_hash_tfm(file, hash, tfm); | ||
117 | |||
118 | if (tfm != ima_shash_tfm) | ||
119 | crypto_free_shash(tfm); | ||
120 | |||
121 | return rc; | ||
122 | } | ||
123 | |||
95 | /* | 124 | /* |
96 | * Calculate the hash of a given buffer | 125 | * Calculate the hash of a given buffer |
97 | */ | 126 | */ |
98 | int ima_calc_buffer_hash(const void *data, int len, char *digest) | 127 | int ima_calc_buffer_hash(const void *buf, int len, struct ima_digest_data *hash) |
99 | { | 128 | { |
100 | struct { | 129 | struct { |
101 | struct shash_desc shash; | 130 | struct shash_desc shash; |
@@ -105,7 +134,11 @@ int ima_calc_buffer_hash(const void *data, int len, char *digest) | |||
105 | desc.shash.tfm = ima_shash_tfm; | 134 | desc.shash.tfm = ima_shash_tfm; |
106 | desc.shash.flags = 0; | 135 | desc.shash.flags = 0; |
107 | 136 | ||
108 | return crypto_shash_digest(&desc.shash, data, len, digest); | 137 | /* this function uses default algo */ |
138 | hash->algo = ima_hash_algo; | ||
139 | hash->length = crypto_shash_digestsize(ima_shash_tfm); | ||
140 | |||
141 | return crypto_shash_digest(&desc.shash, buf, len, hash->digest); | ||
109 | } | 142 | } |
110 | 143 | ||
111 | static void __init ima_pcrread(int idx, u8 *pcr) | 144 | static void __init ima_pcrread(int idx, u8 *pcr) |