diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 11:18:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 11:18:12 -0500 |
commit | 33673dcb372b5d8179c22127ca71deb5f3dc7016 (patch) | |
tree | d182e9dc6aa127375a92b5eb619d6cd2ddc23ce7 /security/integrity/ima/ima_crypto.c | |
parent | fe9453a1dcb5fb146f9653267e78f4a558066f6f (diff) | |
parent | 5b2660326039a32b28766cb4c1a8b1bdcfadc375 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris:
"This is basically a maintenance update for the TPM driver and EVM/IMA"
Fix up conflicts in lib/digsig.c and security/integrity/ima/ima_main.c
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (45 commits)
tpm/ibmvtpm: build only when IBM pseries is configured
ima: digital signature verification using asymmetric keys
ima: rename hash calculation functions
ima: use new crypto_shash API instead of old crypto_hash
ima: add policy support for file system uuid
evm: add file system uuid to EVM hmac
tpm_tis: check pnp_acpi_device return code
char/tpm/tpm_i2c_stm_st33: drop temporary variable for return value
char/tpm/tpm_i2c_stm_st33: remove dead assignment in tpm_st33_i2c_probe
char/tpm/tpm_i2c_stm_st33: Remove __devexit attribute
char/tpm/tpm_i2c_stm_st33: Don't use memcpy for one byte assignment
tpm_i2c_stm_st33: removed unused variables/code
TPM: Wait for TPM_ACCESS tpmRegValidSts to go high at startup
tpm: Fix cancellation of TPM commands (interrupt mode)
tpm: Fix cancellation of TPM commands (polling mode)
tpm: Store TPM vendor ID
TPM: Work around buggy TPMs that block during continue self test
tpm_i2c_stm_st33: fix oops when i2c client is unavailable
char/tpm: Use struct dev_pm_ops for power management
TPM: STMicroelectronics ST33 I2C BUILD STUFF
...
Diffstat (limited to 'security/integrity/ima/ima_crypto.c')
-rw-r--r-- | security/integrity/ima/ima_crypto.c | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index b21ee5b5495a..b691e0f3830c 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c | |||
@@ -19,38 +19,41 @@ | |||
19 | #include <linux/scatterlist.h> | 19 | #include <linux/scatterlist.h> |
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 "ima.h" | 23 | #include "ima.h" |
23 | 24 | ||
24 | static int init_desc(struct hash_desc *desc) | 25 | static struct crypto_shash *ima_shash_tfm; |
26 | |||
27 | int ima_init_crypto(void) | ||
25 | { | 28 | { |
26 | int rc; | 29 | long rc; |
27 | 30 | ||
28 | desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC); | 31 | ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0); |
29 | if (IS_ERR(desc->tfm)) { | 32 | if (IS_ERR(ima_shash_tfm)) { |
30 | pr_info("IMA: failed to load %s transform: %ld\n", | 33 | rc = PTR_ERR(ima_shash_tfm); |
31 | ima_hash, PTR_ERR(desc->tfm)); | 34 | pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc); |
32 | rc = PTR_ERR(desc->tfm); | ||
33 | return rc; | 35 | return rc; |
34 | } | 36 | } |
35 | desc->flags = 0; | 37 | return 0; |
36 | rc = crypto_hash_init(desc); | ||
37 | if (rc) | ||
38 | crypto_free_hash(desc->tfm); | ||
39 | return rc; | ||
40 | } | 38 | } |
41 | 39 | ||
42 | /* | 40 | /* |
43 | * Calculate the MD5/SHA1 file digest | 41 | * Calculate the MD5/SHA1 file digest |
44 | */ | 42 | */ |
45 | int ima_calc_hash(struct file *file, char *digest) | 43 | int ima_calc_file_hash(struct file *file, char *digest) |
46 | { | 44 | { |
47 | struct hash_desc desc; | ||
48 | struct scatterlist sg[1]; | ||
49 | loff_t i_size, offset = 0; | 45 | loff_t i_size, offset = 0; |
50 | char *rbuf; | 46 | char *rbuf; |
51 | int rc, read = 0; | 47 | int rc, read = 0; |
48 | struct { | ||
49 | struct shash_desc shash; | ||
50 | char ctx[crypto_shash_descsize(ima_shash_tfm)]; | ||
51 | } desc; | ||
52 | 52 | ||
53 | rc = init_desc(&desc); | 53 | desc.shash.tfm = ima_shash_tfm; |
54 | desc.shash.flags = 0; | ||
55 | |||
56 | rc = crypto_shash_init(&desc.shash); | ||
54 | if (rc != 0) | 57 | if (rc != 0) |
55 | return rc; | 58 | return rc; |
56 | 59 | ||
@@ -75,41 +78,34 @@ int ima_calc_hash(struct file *file, char *digest) | |||
75 | if (rbuf_len == 0) | 78 | if (rbuf_len == 0) |
76 | break; | 79 | break; |
77 | offset += rbuf_len; | 80 | offset += rbuf_len; |
78 | sg_init_one(sg, rbuf, rbuf_len); | ||
79 | 81 | ||
80 | rc = crypto_hash_update(&desc, sg, rbuf_len); | 82 | rc = crypto_shash_update(&desc.shash, rbuf, rbuf_len); |
81 | if (rc) | 83 | if (rc) |
82 | break; | 84 | break; |
83 | } | 85 | } |
84 | kfree(rbuf); | 86 | kfree(rbuf); |
85 | if (!rc) | 87 | if (!rc) |
86 | rc = crypto_hash_final(&desc, digest); | 88 | rc = crypto_shash_final(&desc.shash, digest); |
87 | if (read) | 89 | if (read) |
88 | file->f_mode &= ~FMODE_READ; | 90 | file->f_mode &= ~FMODE_READ; |
89 | out: | 91 | out: |
90 | crypto_free_hash(desc.tfm); | ||
91 | return rc; | 92 | return rc; |
92 | } | 93 | } |
93 | 94 | ||
94 | /* | 95 | /* |
95 | * Calculate the hash of a given template | 96 | * Calculate the hash of a given buffer |
96 | */ | 97 | */ |
97 | int ima_calc_template_hash(int template_len, void *template, char *digest) | 98 | int ima_calc_buffer_hash(const void *data, int len, char *digest) |
98 | { | 99 | { |
99 | struct hash_desc desc; | 100 | struct { |
100 | struct scatterlist sg[1]; | 101 | struct shash_desc shash; |
101 | int rc; | 102 | char ctx[crypto_shash_descsize(ima_shash_tfm)]; |
103 | } desc; | ||
102 | 104 | ||
103 | rc = init_desc(&desc); | 105 | desc.shash.tfm = ima_shash_tfm; |
104 | if (rc != 0) | 106 | desc.shash.flags = 0; |
105 | return rc; | ||
106 | 107 | ||
107 | sg_init_one(sg, template, template_len); | 108 | return crypto_shash_digest(&desc.shash, data, len, digest); |
108 | rc = crypto_hash_update(&desc, sg, template_len); | ||
109 | if (!rc) | ||
110 | rc = crypto_hash_final(&desc, digest); | ||
111 | crypto_free_hash(desc.tfm); | ||
112 | return rc; | ||
113 | } | 109 | } |
114 | 110 | ||
115 | static void __init ima_pcrread(int idx, u8 *pcr) | 111 | static void __init ima_pcrread(int idx, u8 *pcr) |
@@ -126,12 +122,17 @@ static void __init ima_pcrread(int idx, u8 *pcr) | |||
126 | */ | 122 | */ |
127 | int __init ima_calc_boot_aggregate(char *digest) | 123 | int __init ima_calc_boot_aggregate(char *digest) |
128 | { | 124 | { |
129 | struct hash_desc desc; | ||
130 | struct scatterlist sg; | ||
131 | u8 pcr_i[IMA_DIGEST_SIZE]; | 125 | u8 pcr_i[IMA_DIGEST_SIZE]; |
132 | int rc, i; | 126 | int rc, i; |
127 | struct { | ||
128 | struct shash_desc shash; | ||
129 | char ctx[crypto_shash_descsize(ima_shash_tfm)]; | ||
130 | } desc; | ||
131 | |||
132 | desc.shash.tfm = ima_shash_tfm; | ||
133 | desc.shash.flags = 0; | ||
133 | 134 | ||
134 | rc = init_desc(&desc); | 135 | rc = crypto_shash_init(&desc.shash); |
135 | if (rc != 0) | 136 | if (rc != 0) |
136 | return rc; | 137 | return rc; |
137 | 138 | ||
@@ -139,11 +140,9 @@ int __init ima_calc_boot_aggregate(char *digest) | |||
139 | for (i = TPM_PCR0; i < TPM_PCR8; i++) { | 140 | for (i = TPM_PCR0; i < TPM_PCR8; i++) { |
140 | ima_pcrread(i, pcr_i); | 141 | ima_pcrread(i, pcr_i); |
141 | /* now accumulate with current aggregate */ | 142 | /* now accumulate with current aggregate */ |
142 | sg_init_one(&sg, pcr_i, IMA_DIGEST_SIZE); | 143 | rc = crypto_shash_update(&desc.shash, pcr_i, IMA_DIGEST_SIZE); |
143 | rc = crypto_hash_update(&desc, &sg, IMA_DIGEST_SIZE); | ||
144 | } | 144 | } |
145 | if (!rc) | 145 | if (!rc) |
146 | crypto_hash_final(&desc, digest); | 146 | crypto_shash_final(&desc.shash, digest); |
147 | crypto_free_hash(desc.tfm); | ||
148 | return rc; | 147 | return rc; |
149 | } | 148 | } |