ima: provide buffer hash calculation function
authorDmitry Kasatkin <dmitry.kasatkin@huawei.com>
Thu, 17 Apr 2014 09:01:40 +0000 (12:01 +0300)
committerMimi Zohar <zohar@linux.vnet.ibm.com>
Thu, 18 Feb 2016 22:14:28 +0000 (17:14 -0500)
This patch provides convenient buffer hash calculation function.

Changelog v3:
- fix while hash calculation - Dmitry
v1:
- rewrite to support loff_t sized buffers - Mimi
  (based on Fenguang Wu's testing)

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
security/integrity/ima/ima.h
security/integrity/ima/ima_crypto.c

index b7e793501bdbc3a9e43e4bee734ec645d54ad0eb..2c5262f2823f11931b7ee7d7d2a4791335730900 100644 (file)
@@ -107,6 +107,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
                           const char *op, struct inode *inode,
                           const unsigned char *filename);
 int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
+int ima_calc_buffer_hash(const void *buf, loff_t len,
+                        struct ima_digest_data *hash);
 int ima_calc_field_array_hash(struct ima_field_data *field_data,
                              struct ima_template_desc *desc, int num_fields,
                              struct ima_digest_data *hash);
index fb30ce406af41df4ce7f2e4d880963c30926b122..fccb6ceb388bc69ef42e99f6ef73bec32a9bf12d 100644 (file)
@@ -519,6 +519,53 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data,
        return rc;
 }
 
+static int calc_buffer_shash_tfm(const void *buf, loff_t size,
+                               struct ima_digest_data *hash,
+                               struct crypto_shash *tfm)
+{
+       SHASH_DESC_ON_STACK(shash, tfm);
+       unsigned int len;
+       int rc;
+
+       shash->tfm = tfm;
+       shash->flags = 0;
+
+       hash->length = crypto_shash_digestsize(tfm);
+
+       rc = crypto_shash_init(shash);
+       if (rc != 0)
+               return rc;
+
+       while (size) {
+               len = size < PAGE_SIZE ? size : PAGE_SIZE;
+               rc = crypto_shash_update(shash, buf, len);
+               if (rc)
+                       break;
+               buf += len;
+               size -= len;
+       }
+
+       if (!rc)
+               rc = crypto_shash_final(shash, hash->digest);
+       return rc;
+}
+
+int ima_calc_buffer_hash(const void *buf, loff_t len,
+                        struct ima_digest_data *hash)
+{
+       struct crypto_shash *tfm;
+       int rc;
+
+       tfm = ima_alloc_tfm(hash->algo);
+       if (IS_ERR(tfm))
+               return PTR_ERR(tfm);
+
+       rc = calc_buffer_shash_tfm(buf, len, hash, tfm);
+
+       ima_free_tfm(tfm);
+       return rc;
+}
+
 static void __init ima_pcrread(int idx, u8 *pcr)
 {
        if (!ima_used_chip)