summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDmitry Kasatkin <dmitry.kasatkin@huawei.com>2014-04-17 11:01:40 +0200
committerMimi Zohar <zohar@linux.vnet.ibm.com>2016-02-18 23:14:28 +0100
commit11d7646df8e800f434ff710ad6100acbea59068e (patch)
tree71f8ba704fcde9eb3ea65b4916459dcc3bee2566 /security
parentvfs: define kernel_read_file_id enumeration (diff)
downloadlinux-11d7646df8e800f434ff710ad6100acbea59068e.tar.xz
linux-11d7646df8e800f434ff710ad6100acbea59068e.zip
ima: provide buffer hash calculation function
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>
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima.h2
-rw-r--r--security/integrity/ima/ima_crypto.c47
2 files changed, 49 insertions, 0 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b7e793501bdb..2c5262f2823f 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -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);
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index fb30ce406af4..fccb6ceb388b 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -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)