diff options
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 b21ee5b5495..b691e0f3830 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -19,38 +19,41 @@ #include <linux/scatterlist.h> #include <linux/err.h> #include <linux/slab.h> +#include <crypto/hash.h> #include "ima.h" -static int init_desc(struct hash_desc *desc) +static struct crypto_shash *ima_shash_tfm; + +int ima_init_crypto(void) { - int rc; + long rc; - desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(desc->tfm)) { - pr_info("IMA: failed to load %s transform: %ld\n", - ima_hash, PTR_ERR(desc->tfm)); - rc = PTR_ERR(desc->tfm); + ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0); + if (IS_ERR(ima_shash_tfm)) { + rc = PTR_ERR(ima_shash_tfm); + pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc); return rc; } - desc->flags = 0; - rc = crypto_hash_init(desc); - if (rc) - crypto_free_hash(desc->tfm); - return rc; + return 0; } /* * Calculate the MD5/SHA1 file digest */ -int ima_calc_hash(struct file *file, char *digest) +int ima_calc_file_hash(struct file *file, char *digest) { - struct hash_desc desc; - struct scatterlist sg[1]; loff_t i_size, offset = 0; char *rbuf; int rc, read = 0; + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(ima_shash_tfm)]; + } desc; - rc = init_desc(&desc); + desc.shash.tfm = ima_shash_tfm; + desc.shash.flags = 0; + + rc = crypto_shash_init(&desc.shash); if (rc != 0) return rc; @@ -75,41 +78,34 @@ int ima_calc_hash(struct file *file, char *digest) if (rbuf_len == 0) break; offset += rbuf_len; - sg_init_one(sg, rbuf, rbuf_len); - rc = crypto_hash_update(&desc, sg, rbuf_len); + rc = crypto_shash_update(&desc.shash, rbuf, rbuf_len); if (rc) break; } kfree(rbuf); if (!rc) - rc = crypto_hash_final(&desc, digest); + rc = crypto_shash_final(&desc.shash, digest); if (read) file->f_mode &= ~FMODE_READ; out: - crypto_free_hash(desc.tfm); return rc; } /* - * Calculate the hash of a given template + * Calculate the hash of a given buffer */ -int ima_calc_template_hash(int template_len, void *template, char *digest) +int ima_calc_buffer_hash(const void *data, int len, char *digest) { - struct hash_desc desc; - struct scatterlist sg[1]; - int rc; + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(ima_shash_tfm)]; + } desc; - rc = init_desc(&desc); - if (rc != 0) - return rc; + desc.shash.tfm = ima_shash_tfm; + desc.shash.flags = 0; - sg_init_one(sg, template, template_len); - rc = crypto_hash_update(&desc, sg, template_len); - if (!rc) - rc = crypto_hash_final(&desc, digest); - crypto_free_hash(desc.tfm); - return rc; + return crypto_shash_digest(&desc.shash, data, len, digest); } static void __init ima_pcrread(int idx, u8 *pcr) @@ -126,12 +122,17 @@ static void __init ima_pcrread(int idx, u8 *pcr) */ int __init ima_calc_boot_aggregate(char *digest) { - struct hash_desc desc; - struct scatterlist sg; u8 pcr_i[IMA_DIGEST_SIZE]; int rc, i; + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(ima_shash_tfm)]; + } desc; + + desc.shash.tfm = ima_shash_tfm; + desc.shash.flags = 0; - rc = init_desc(&desc); + rc = crypto_shash_init(&desc.shash); if (rc != 0) return rc; @@ -139,11 +140,9 @@ int __init ima_calc_boot_aggregate(char *digest) for (i = TPM_PCR0; i < TPM_PCR8; i++) { ima_pcrread(i, pcr_i); /* now accumulate with current aggregate */ - sg_init_one(&sg, pcr_i, IMA_DIGEST_SIZE); - rc = crypto_hash_update(&desc, &sg, IMA_DIGEST_SIZE); + rc = crypto_shash_update(&desc.shash, pcr_i, IMA_DIGEST_SIZE); } if (!rc) - crypto_hash_final(&desc, digest); - crypto_free_hash(desc.tfm); + crypto_shash_final(&desc.shash, digest); return rc; } |