aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_crypto.c
diff options
context:
space:
mode:
authorDmitry Kasatkin <d.kasatkin@samsung.com>2013-04-25 03:43:56 -0400
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)
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 @@
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <crypto/hash.h> 22#include <crypto/hash.h>
23#include <crypto/hash_info.h>
23#include "ima.h" 24#include "ima.h"
24 25
25static struct crypto_shash *ima_shash_tfm; 26static struct crypto_shash *ima_shash_tfm;
@@ -28,10 +29,11 @@ int ima_init_crypto(void)
28{ 29{
29 long rc; 30 long rc;
30 31
31 ima_shash_tfm = crypto_alloc_shash(ima_hash, 0, 0); 32 ima_shash_tfm = crypto_alloc_shash(hash_algo_name[ima_hash_algo], 0, 0);
32 if (IS_ERR(ima_shash_tfm)) { 33 if (IS_ERR(ima_shash_tfm)) {
33 rc = PTR_ERR(ima_shash_tfm); 34 rc = PTR_ERR(ima_shash_tfm);
34 pr_err("Can not allocate %s (reason: %ld)\n", ima_hash, rc); 35 pr_err("Can not allocate %s (reason: %ld)\n",
36 hash_algo_name[ima_hash_algo], rc);
35 return rc; 37 return rc;
36 } 38 }
37 return 0; 39 return 0;
@@ -40,17 +42,19 @@ int ima_init_crypto(void)
40/* 42/*
41 * Calculate the MD5/SHA1 file digest 43 * Calculate the MD5/SHA1 file digest
42 */ 44 */
43int ima_calc_file_hash(struct file *file, char *digest) 45static int ima_calc_file_hash_tfm(struct file *file,
46 struct ima_digest_data *hash,
47 struct crypto_shash *tfm)
44{ 48{
45 loff_t i_size, offset = 0; 49 loff_t i_size, offset = 0;
46 char *rbuf; 50 char *rbuf;
47 int rc, read = 0; 51 int rc, read = 0;
48 struct { 52 struct {
49 struct shash_desc shash; 53 struct shash_desc shash;
50 char ctx[crypto_shash_descsize(ima_shash_tfm)]; 54 char ctx[crypto_shash_descsize(tfm)];
51 } desc; 55 } desc;
52 56
53 desc.shash.tfm = ima_shash_tfm; 57 desc.shash.tfm = tfm;
54 desc.shash.flags = 0; 58 desc.shash.flags = 0;
55 59
56 rc = crypto_shash_init(&desc.shash); 60 rc = crypto_shash_init(&desc.shash);
@@ -85,17 +89,42 @@ int ima_calc_file_hash(struct file *file, char *digest)
85 } 89 }
86 kfree(rbuf); 90 kfree(rbuf);
87 if (!rc) 91 if (!rc)
88 rc = crypto_shash_final(&desc.shash, digest); 92 rc = crypto_shash_final(&desc.shash, hash->digest);
89 if (read) 93 if (read)
90 file->f_mode &= ~FMODE_READ; 94 file->f_mode &= ~FMODE_READ;
91out: 95out:
92 return rc; 96 return rc;
93} 97}
94 98
99int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
100{
101 struct crypto_shash *tfm = ima_shash_tfm;
102 int rc;
103
104 if (hash->algo != ima_hash_algo && hash->algo < HASH_ALGO__LAST) {
105 tfm = crypto_alloc_shash(hash_algo_name[hash->algo], 0, 0);
106 if (IS_ERR(tfm)) {
107 rc = PTR_ERR(tfm);
108 pr_err("Can not allocate %s (reason: %d)\n",
109 hash_algo_name[hash->algo], rc);
110 return rc;
111 }
112 }
113
114 hash->length = crypto_shash_digestsize(tfm);
115
116 rc = ima_calc_file_hash_tfm(file, hash, tfm);
117
118 if (tfm != ima_shash_tfm)
119 crypto_free_shash(tfm);
120
121 return rc;
122}
123
95/* 124/*
96 * Calculate the hash of a given buffer 125 * Calculate the hash of a given buffer
97 */ 126 */
98int ima_calc_buffer_hash(const void *data, int len, char *digest) 127int ima_calc_buffer_hash(const void *buf, int len, struct ima_digest_data *hash)
99{ 128{
100 struct { 129 struct {
101 struct shash_desc shash; 130 struct shash_desc shash;
@@ -105,7 +134,11 @@ int ima_calc_buffer_hash(const void *data, int len, char *digest)
105 desc.shash.tfm = ima_shash_tfm; 134 desc.shash.tfm = ima_shash_tfm;
106 desc.shash.flags = 0; 135 desc.shash.flags = 0;
107 136
108 return crypto_shash_digest(&desc.shash, data, len, digest); 137 /* this function uses default algo */
138 hash->algo = ima_hash_algo;
139 hash->length = crypto_shash_digestsize(ima_shash_tfm);
140
141 return crypto_shash_digest(&desc.shash, buf, len, hash->digest);
109} 142}
110 143
111static void __init ima_pcrread(int idx, u8 *pcr) 144static void __init ima_pcrread(int idx, u8 *pcr)