diff options
| -rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
| -rw-r--r-- | security/integrity/ima/ima_crypto.c | 75 | ||||
| -rw-r--r-- | security/integrity/ima/ima_init.c | 3 |
3 files changed, 41 insertions, 38 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index ab68bed8ac36..5a94f9c92605 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
| @@ -89,6 +89,7 @@ int ima_calc_template_hash(int template_len, void *template, char *digest); | |||
| 89 | int ima_calc_boot_aggregate(char *digest); | 89 | int ima_calc_boot_aggregate(char *digest); |
| 90 | void ima_add_violation(struct inode *inode, const unsigned char *filename, | 90 | void ima_add_violation(struct inode *inode, const unsigned char *filename, |
| 91 | const char *op, const char *cause); | 91 | const char *op, const char *cause); |
| 92 | int ima_init_crypto(void); | ||
| 92 | 93 | ||
| 93 | /* | 94 | /* |
| 94 | * used to protect h_table and sha_table | 95 | * used to protect h_table and sha_table |
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index b21ee5b5495a..920f49cfbf13 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c | |||
| @@ -19,24 +19,22 @@ | |||
| 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 | /* |
| @@ -44,13 +42,18 @@ static int init_desc(struct hash_desc *desc) | |||
| 44 | */ | 42 | */ |
| 45 | int ima_calc_hash(struct file *file, char *digest) | 43 | int ima_calc_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,19 +78,17 @@ 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 | ||
| @@ -96,20 +97,15 @@ out: | |||
| 96 | */ | 97 | */ |
| 97 | int ima_calc_template_hash(int template_len, void *template, char *digest) | 98 | int ima_calc_template_hash(int template_len, void *template, 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, template, template_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 | } |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index b5dfd534f13d..162ea723db3d 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
| @@ -85,6 +85,9 @@ int __init ima_init(void) | |||
| 85 | if (!ima_used_chip) | 85 | if (!ima_used_chip) |
| 86 | pr_info("IMA: No TPM chip found, activating TPM-bypass!\n"); | 86 | pr_info("IMA: No TPM chip found, activating TPM-bypass!\n"); |
| 87 | 87 | ||
| 88 | rc = ima_init_crypto(); | ||
| 89 | if (rc) | ||
| 90 | return rc; | ||
| 88 | ima_add_boot_aggregate(); /* boot aggregate must be first entry */ | 91 | ima_add_boot_aggregate(); /* boot aggregate must be first entry */ |
| 89 | ima_init_policy(); | 92 | ima_init_policy(); |
| 90 | 93 | ||
