summaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_crypto.c
diff options
context:
space:
mode:
authorDmitry Kasatkin <d.kasatkin@samsung.com>2013-04-25 10:43:56 +0300
committerMimi Zohar <zohar@linux.vnet.ibm.com>2013-10-25 17:16:58 -0400
commitc7c8bb237fdbff932b5e431aebee5ce862ea07d1 (patch)
tree4cdbc7c250dd4418b47ab45dd1108848b50f8cff /security/integrity/ima/ima_crypto.c
parent3fe78ca2fb1d61ea598e63fcbf38aec76b36b3a8 (diff)
downloadlinux-c7c8bb237fdbff932b5e431aebee5ce862ea07d1.tar.bz2
ima: provide support for arbitrary hash algorithms
In preparation of supporting more hash algorithms with larger hash sizes needed for signature verification, this patch replaces the 20 byte sized digest, with a more flexible structure. The new structure includes the hash algorithm, digest size, and digest. Changelog: - recalculate filedata hash for the measurement list, if the signature hash digest size is greater than 20 bytes. - use generic HASH_ALGO_ - make ima_calc_file_hash static - scripts lindent and checkpatch fixes Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity/ima/ima_crypto.c')
-rw-r--r--security/integrity/ima/ima_crypto.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index a02e0791cf15..2fd178651467 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -20,6 +20,7 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <crypto/hash.h>
+#include <crypto/hash_info.h>
#include "ima.h"
static struct crypto_shash *ima_shash_tfm;
@@ -28,10 +29,11 @@ int ima_init_crypto(void)
{
long rc;
- ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0);
+ ima_shash_tfm = crypto_alloc_shash(hash_algo_name[ima_hash_algo], 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);
+ pr_err("Can not allocate %s (reason: %ld)\n",
+ hash_algo_name[ima_hash_algo], rc);
return rc;
}
return 0;
@@ -40,17 +42,19 @@ int ima_init_crypto(void)
/*
* Calculate the MD5/SHA1 file digest
*/
-int ima_calc_file_hash(struct file *file, char *digest)
+static int ima_calc_file_hash_tfm(struct file *file,
+ struct ima_digest_data *hash,
+ struct crypto_shash *tfm)
{
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)];
+ char ctx[crypto_shash_descsize(tfm)];
} desc;
- desc.shash.tfm = ima_shash_tfm;
+ desc.shash.tfm = tfm;
desc.shash.flags = 0;
rc = crypto_shash_init(&desc.shash);
@@ -85,17 +89,42 @@ int ima_calc_file_hash(struct file *file, char *digest)
}
kfree(rbuf);
if (!rc)
- rc = crypto_shash_final(&desc.shash, digest);
+ rc = crypto_shash_final(&desc.shash, hash->digest);
if (read)
file->f_mode &= ~FMODE_READ;
out:
return rc;
}
+int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
+{
+ struct crypto_shash *tfm = ima_shash_tfm;
+ int rc;
+
+ if (hash->algo != ima_hash_algo && hash->algo < HASH_ALGO__LAST) {
+ tfm = crypto_alloc_shash(hash_algo_name[hash->algo], 0, 0);
+ if (IS_ERR(tfm)) {
+ rc = PTR_ERR(tfm);
+ pr_err("Can not allocate %s (reason: %d)\n",
+ hash_algo_name[hash->algo], rc);
+ return rc;
+ }
+ }
+
+ hash->length = crypto_shash_digestsize(tfm);
+
+ rc = ima_calc_file_hash_tfm(file, hash, tfm);
+
+ if (tfm != ima_shash_tfm)
+ crypto_free_shash(tfm);
+
+ return rc;
+}
+
/*
* Calculate the hash of a given buffer
*/
-int ima_calc_buffer_hash(const void *data, int len, char *digest)
+int ima_calc_buffer_hash(const void *buf, int len, struct ima_digest_data *hash)
{
struct {
struct shash_desc shash;
@@ -105,7 +134,11 @@ int ima_calc_buffer_hash(const void *data, int len, char *digest)
desc.shash.tfm = ima_shash_tfm;
desc.shash.flags = 0;
- return crypto_shash_digest(&desc.shash, data, len, digest);
+ /* this function uses default algo */
+ hash->algo = ima_hash_algo;
+ hash->length = crypto_shash_digestsize(ima_shash_tfm);
+
+ return crypto_shash_digest(&desc.shash, buf, len, hash->digest);
}
static void __init ima_pcrread(int idx, u8 *pcr)