summaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_crypto.c')
-rw-r--r--security/integrity/ima/ima_crypto.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 22be23f13b3d..676e0292dfec 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -137,26 +137,46 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
}
/*
- * Calculate the hash of a given buffer
+ * Calculate the hash of template data
*/
-static int ima_calc_buffer_hash_tfm(const void *buf, int len,
- struct ima_digest_data *hash,
- struct crypto_shash *tfm)
+static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data,
+ int num_fields,
+ struct ima_digest_data *hash,
+ struct crypto_shash *tfm)
{
struct {
struct shash_desc shash;
char ctx[crypto_shash_descsize(tfm)];
} desc;
+ int rc, i;
desc.shash.tfm = tfm;
desc.shash.flags = 0;
hash->length = crypto_shash_digestsize(tfm);
- return crypto_shash_digest(&desc.shash, buf, len, hash->digest);
+ rc = crypto_shash_init(&desc.shash);
+ if (rc != 0)
+ return rc;
+
+ for (i = 0; i < num_fields; i++) {
+ rc = crypto_shash_update(&desc.shash,
+ (const u8 *) &field_data[i].len,
+ sizeof(field_data[i].len));
+ rc = crypto_shash_update(&desc.shash, field_data[i].data,
+ field_data[i].len);
+ if (rc)
+ break;
+ }
+
+ if (!rc)
+ rc = crypto_shash_final(&desc.shash, hash->digest);
+
+ return rc;
}
-int ima_calc_buffer_hash(const void *buf, int len, struct ima_digest_data *hash)
+int ima_calc_field_array_hash(struct ima_field_data *field_data, int num_fields,
+ struct ima_digest_data *hash)
{
struct crypto_shash *tfm;
int rc;
@@ -165,7 +185,7 @@ int ima_calc_buffer_hash(const void *buf, int len, struct ima_digest_data *hash)
if (IS_ERR(tfm))
return PTR_ERR(tfm);
- rc = ima_calc_buffer_hash_tfm(buf, len, hash, tfm);
+ rc = ima_calc_field_array_hash_tfm(field_data, num_fields, hash, tfm);
ima_free_tfm(tfm);