Skip to content

Commit 9fa8e76

Browse files
cinghioGithubmimizohar
authored andcommitted
ima: add crypto agility support for template-hash algorithm
The template hash showed by the ascii_runtime_measurements and binary_runtime_measurements is the one calculated using sha1 and there is no possibility to change this value, despite the fact that the template hash is calculated using the hash algorithms corresponding to all the PCR banks configured in the TPM. Add the support to retrieve the ima log with the template data hash calculated with a specific hash algorithm. Add a new file in the securityfs ima directory for each hash algo configured in a PCR bank of the TPM. Each new file has the name with the following structure: {binary, ascii}_runtime_measurements_<hash_algo_name> Legacy files are kept, to avoid breaking existing applications, but as symbolic links which point to {binary, ascii}_runtime_measurements_sha1 files. These two files are created even if a TPM chip is not detected or the sha1 bank is not configured in the TPM. As example, in the case a TPM chip is present and sha256 is the only configured PCR bank, the listing of the securityfs ima directory is the following: lr--r--r-- [...] ascii_runtime_measurements -> ascii_runtime_measurements_sha1 -r--r----- [...] ascii_runtime_measurements_sha1 -r--r----- [...] ascii_runtime_measurements_sha256 lr--r--r-- [...] binary_runtime_measurements -> binary_runtime_measurements_sha1 -r--r----- [...] binary_runtime_measurements_sha1 -r--r----- [...] binary_runtime_measurements_sha256 --w------- [...] policy -r--r----- [...] runtime_measurements_count -r--r----- [...] violations Signed-off-by: Enrico Bravi <enrico.bravi@polito.it> Signed-off-by: Silvia Sisinni <silvia.sisinni@polito.it> Reviewed-by: Roberto Sassu <roberto.sassu@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
1 parent 5e2e4d0 commit 9fa8e76

File tree

4 files changed

+132
-18
lines changed

4 files changed

+132
-18
lines changed

security/integrity/ima/ima.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,19 @@ extern int ima_policy_flag;
4949
/* bitset of digests algorithms allowed in the setxattr hook */
5050
extern atomic_t ima_setxattr_allowed_hash_algorithms;
5151

52+
/* IMA hash algorithm description */
53+
struct ima_algo_desc {
54+
struct crypto_shash *tfm;
55+
enum hash_algo algo;
56+
};
57+
5258
/* set during initialization */
5359
extern int ima_hash_algo __ro_after_init;
5460
extern int ima_sha1_idx __ro_after_init;
5561
extern int ima_hash_algo_idx __ro_after_init;
5662
extern int ima_extra_slots __ro_after_init;
63+
extern struct ima_algo_desc *ima_algo_array __ro_after_init;
64+
5765
extern int ima_appraise;
5866
extern struct tpm_chip *ima_tpm_chip;
5967
extern const char boot_aggregate_name[];

security/integrity/ima/ima_crypto.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ MODULE_PARM_DESC(ahash_bufsize, "Maximum ahash buffer size");
5757
static struct crypto_shash *ima_shash_tfm;
5858
static struct crypto_ahash *ima_ahash_tfm;
5959

60-
struct ima_algo_desc {
61-
struct crypto_shash *tfm;
62-
enum hash_algo algo;
63-
};
64-
6560
int ima_sha1_idx __ro_after_init;
6661
int ima_hash_algo_idx __ro_after_init;
6762
/*
@@ -70,7 +65,7 @@ int ima_hash_algo_idx __ro_after_init;
7065
*/
7166
int ima_extra_slots __ro_after_init;
7267

73-
static struct ima_algo_desc *ima_algo_array;
68+
struct ima_algo_desc *ima_algo_array __ro_after_init;
7469

7570
static int __init ima_init_ima_crypto(void)
7671
{

security/integrity/ima/ima_fs.c

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,31 @@ void ima_putc(struct seq_file *m, void *data, int datalen)
116116
seq_putc(m, *(char *)data++);
117117
}
118118

119+
static struct dentry **ascii_securityfs_measurement_lists __ro_after_init;
120+
static struct dentry **binary_securityfs_measurement_lists __ro_after_init;
121+
static int securityfs_measurement_list_count __ro_after_init;
122+
123+
static void lookup_template_data_hash_algo(int *algo_idx, enum hash_algo *algo,
124+
struct seq_file *m,
125+
struct dentry **lists)
126+
{
127+
struct dentry *dentry;
128+
int i;
129+
130+
dentry = file_dentry(m->file);
131+
132+
for (i = 0; i < securityfs_measurement_list_count; i++) {
133+
if (dentry == lists[i]) {
134+
*algo_idx = i;
135+
*algo = ima_algo_array[i].algo;
136+
break;
137+
}
138+
}
139+
}
140+
119141
/* print format:
120142
* 32bit-le=pcr#
121-
* char[20]=template digest
143+
* char[n]=template digest
122144
* 32bit-le=template name size
123145
* char[n]=template name
124146
* [eventdata length]
@@ -132,7 +154,15 @@ int ima_measurements_show(struct seq_file *m, void *v)
132154
char *template_name;
133155
u32 pcr, namelen, template_data_len; /* temporary fields */
134156
bool is_ima_template = false;
135-
int i;
157+
enum hash_algo algo;
158+
int i, algo_idx;
159+
160+
algo_idx = ima_sha1_idx;
161+
algo = HASH_ALGO_SHA1;
162+
163+
if (m->file != NULL)
164+
lookup_template_data_hash_algo(&algo_idx, &algo, m,
165+
binary_securityfs_measurement_lists);
136166

137167
/* get entry */
138168
e = qe->entry;
@@ -151,7 +181,7 @@ int ima_measurements_show(struct seq_file *m, void *v)
151181
ima_putc(m, &pcr, sizeof(e->pcr));
152182

153183
/* 2nd: template digest */
154-
ima_putc(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
184+
ima_putc(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
155185

156186
/* 3rd: template name size */
157187
namelen = !ima_canonical_fmt ? strlen(template_name) :
@@ -220,7 +250,15 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
220250
struct ima_queue_entry *qe = v;
221251
struct ima_template_entry *e;
222252
char *template_name;
223-
int i;
253+
enum hash_algo algo;
254+
int i, algo_idx;
255+
256+
algo_idx = ima_sha1_idx;
257+
algo = HASH_ALGO_SHA1;
258+
259+
if (m->file != NULL)
260+
lookup_template_data_hash_algo(&algo_idx, &algo, m,
261+
ascii_securityfs_measurement_lists);
224262

225263
/* get entry */
226264
e = qe->entry;
@@ -233,8 +271,8 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
233271
/* 1st: PCR used (config option) */
234272
seq_printf(m, "%2d ", e->pcr);
235273

236-
/* 2nd: SHA1 template hash */
237-
ima_print_digest(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
274+
/* 2nd: template hash */
275+
ima_print_digest(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
238276

239277
/* 3th: template name */
240278
seq_printf(m, " %s", template_name);
@@ -379,6 +417,71 @@ static const struct seq_operations ima_policy_seqops = {
379417
};
380418
#endif
381419

420+
static void __init remove_securityfs_measurement_lists(struct dentry **lists)
421+
{
422+
int i;
423+
424+
if (lists) {
425+
for (i = 0; i < securityfs_measurement_list_count; i++)
426+
securityfs_remove(lists[i]);
427+
428+
kfree(lists);
429+
}
430+
431+
securityfs_measurement_list_count = 0;
432+
}
433+
434+
static int __init create_securityfs_measurement_lists(void)
435+
{
436+
char file_name[NAME_MAX + 1];
437+
struct dentry *dentry;
438+
u16 algo;
439+
int i;
440+
441+
securityfs_measurement_list_count = NR_BANKS(ima_tpm_chip);
442+
443+
if (ima_sha1_idx >= NR_BANKS(ima_tpm_chip))
444+
securityfs_measurement_list_count++;
445+
446+
ascii_securityfs_measurement_lists =
447+
kcalloc(securityfs_measurement_list_count, sizeof(struct dentry *),
448+
GFP_KERNEL);
449+
if (!ascii_securityfs_measurement_lists)
450+
return -ENOMEM;
451+
452+
binary_securityfs_measurement_lists =
453+
kcalloc(securityfs_measurement_list_count, sizeof(struct dentry *),
454+
GFP_KERNEL);
455+
if (!binary_securityfs_measurement_lists)
456+
return -ENOMEM;
457+
458+
for (i = 0; i < securityfs_measurement_list_count; i++) {
459+
algo = ima_algo_array[i].algo;
460+
461+
sprintf(file_name, "ascii_runtime_measurements_%s",
462+
hash_algo_name[algo]);
463+
dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
464+
ima_dir, NULL,
465+
&ima_ascii_measurements_ops);
466+
if (IS_ERR(dentry))
467+
return PTR_ERR(dentry);
468+
469+
ascii_securityfs_measurement_lists[i] = dentry;
470+
471+
sprintf(file_name, "binary_runtime_measurements_%s",
472+
hash_algo_name[algo]);
473+
dentry = securityfs_create_file(file_name, S_IRUSR | S_IRGRP,
474+
ima_dir, NULL,
475+
&ima_measurements_ops);
476+
if (IS_ERR(dentry))
477+
return PTR_ERR(dentry);
478+
479+
binary_securityfs_measurement_lists[i] = dentry;
480+
}
481+
482+
return 0;
483+
}
484+
382485
/*
383486
* ima_open_policy: sequentialize access to the policy file
384487
*/
@@ -454,6 +557,9 @@ int __init ima_fs_init(void)
454557
{
455558
int ret;
456559

560+
ascii_securityfs_measurement_lists = NULL;
561+
binary_securityfs_measurement_lists = NULL;
562+
457563
ima_dir = securityfs_create_dir("ima", integrity_dir);
458564
if (IS_ERR(ima_dir))
459565
return PTR_ERR(ima_dir);
@@ -465,19 +571,21 @@ int __init ima_fs_init(void)
465571
goto out;
466572
}
467573

574+
ret = create_securityfs_measurement_lists();
575+
if (ret != 0)
576+
goto out;
577+
468578
binary_runtime_measurements =
469-
securityfs_create_file("binary_runtime_measurements",
470-
S_IRUSR | S_IRGRP, ima_dir, NULL,
471-
&ima_measurements_ops);
579+
securityfs_create_symlink("binary_runtime_measurements", ima_dir,
580+
"binary_runtime_measurements_sha1", NULL);
472581
if (IS_ERR(binary_runtime_measurements)) {
473582
ret = PTR_ERR(binary_runtime_measurements);
474583
goto out;
475584
}
476585

477586
ascii_runtime_measurements =
478-
securityfs_create_file("ascii_runtime_measurements",
479-
S_IRUSR | S_IRGRP, ima_dir, NULL,
480-
&ima_ascii_measurements_ops);
587+
securityfs_create_symlink("ascii_runtime_measurements", ima_dir,
588+
"ascii_runtime_measurements_sha1", NULL);
481589
if (IS_ERR(ascii_runtime_measurements)) {
482590
ret = PTR_ERR(ascii_runtime_measurements);
483591
goto out;
@@ -515,6 +623,8 @@ int __init ima_fs_init(void)
515623
securityfs_remove(runtime_measurements_count);
516624
securityfs_remove(ascii_runtime_measurements);
517625
securityfs_remove(binary_runtime_measurements);
626+
remove_securityfs_measurement_lists(ascii_securityfs_measurement_lists);
627+
remove_securityfs_measurement_lists(binary_securityfs_measurement_lists);
518628
securityfs_remove(ima_symlink);
519629
securityfs_remove(ima_dir);
520630

security/integrity/ima/ima_kexec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
3030
goto out;
3131
}
3232

33+
file.file = NULL;
3334
file.size = segment_size;
3435
file.read_pos = 0;
3536
file.count = sizeof(khdr); /* reserved space */

0 commit comments

Comments
 (0)