From: Roberto Sassu <roberto.sassu@huaweicloud.com>
To: Enrico Bravi <enrico.bravi@polito.it>,
linux-integrity@vger.kernel.org, zohar@linux.ibm.com,
roberto.sassu@huawei.com
Cc: Silvia Sisinni <silvia.sisinni@polito.it>
Subject: Re: [PATCH v3] ima: add crypto agility support for template-hash algorithm
Date: Thu, 25 Jan 2024 09:49:40 +0100 [thread overview]
Message-ID: <ec47723ee4712458dea2810820a05c301c1137d2.camel@huaweicloud.com> (raw)
In-Reply-To: <aaf771a59ff6c1fd99e579028f63f2278f6bed23.camel@huaweicloud.com>
On Thu, 2024-01-25 at 09:30 +0100, Roberto Sassu wrote:
> On Wed, 2024-01-24 at 20:32 +0100, Enrico Bravi wrote:
> > 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.
>
> Hi Enrico
>
> the missing part is that we should not modify existing files, to avoid
> breaking existing applications.
Forgot:
please use scripts/get_maintainer.pl to find the correct recipients of
the patch (I think you only need to include maintainers and reviewers).
Thanks
Roberto
> > 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
> > for the PCR banks of the TPM. Each new file has the name with the following
> > structure:
> >
> > {binary, ascii}_runtime_measurements_<hash_algo_name>
> >
> > The <hash_algo_name> is used to select the template data hash algorithm to show
> > in ima_ascii_measurements_show() and in ima_measurements_show().
> > Legacy files are kept but as sysmbolic links which point to
>
> Typo. Please use codespell on the patch.
>
> > {binary, ascii}_runtime_measurements_sha1 files. These two files are created
> > even if a TPM chip is not detected.
> >
> > As example, in the case a TPM chip is present and sha1 and sha256 are the
> > configured PCR banks, the listing of the security/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
>
> Ok, great.
>
> > Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>
> > Signed-off-by: Silvia Sisinni <silvia.sisinni@polito.it>
> >
> > ---
> >
> > v3:
> > - Added create_measurements_list_files function for measurements files creation.
> > - Parametrized the remove_measurements_list_files function and add NULL
> > check before freeing files' list.
> > - Removed algorithm selection based on file name during ima_measurements_show
> > and ima_ascii_mesurements_show, and selecting it comparing dentry address.
> > - Allocate also sha1 file following the schema
> > {binary, ascii}_runtime_measurements_<hash_algo_name> and keep legacy
> > files as symbolic links to those files.
> > - Allocate measurements files lists even if a TPM chip is not detected,
> > adding only sha1 files.
> >
> > v2:
> > - Changed the behaviour of configuring at boot time the template data hash
> > algorithm.
> > - Removed template data hash algo name prefix.
> > - Removed ima_template_hash command line option.
> > - Introducing a new file in the securityfs ima subdir for each PCR banks
> > algorithm configured in the TPM.
> > (suggested by Roberto)
> >
> > security/integrity/ima/ima_fs.c | 145 +++++++++++++++++++++++++++++---
> > 1 file changed, 131 insertions(+), 14 deletions(-)
> >
> > diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> > index cd1683dad3bf..fb65ba9426a1 100644
> > --- a/security/integrity/ima/ima_fs.c
> > +++ b/security/integrity/ima/ima_fs.c
> > @@ -116,9 +116,12 @@ void ima_putc(struct seq_file *m, void *data, int datalen)
> > seq_putc(m, *(char *)data++);
> > }
> >
> > +static struct dentry **ima_ascii_measurements_files;
> > +static struct dentry **ima_binary_measurements_files;
> > +
> > /* print format:
> > * 32bit-le=pcr#
> > - * char[20]=template digest
> > + * char[n]=template digest
> > * 32bit-le=template name size
> > * char[n]=template name
> > * [eventdata length]
> > @@ -130,9 +133,25 @@ int ima_measurements_show(struct seq_file *m, void *v)
> > struct ima_queue_entry *qe = v;
> > struct ima_template_entry *e;
> > char *template_name;
> > + struct dentry *dentry;
> > u32 pcr, namelen, template_data_len; /* temporary fields */
> > bool is_ima_template = false;
> > - int i;
> > + int i, algo_idx;
> > + enum hash_algo algo;
> > +
> > + dentry = m->file->f_path.dentry;
>
> I like more file_dentry(m->file).
>
> > + algo_idx = ima_sha1_idx;
> > + algo = HASH_ALGO_SHA1;
> > +
> > + if (ima_tpm_chip) {
> > + for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
> > + if (dentry == ima_binary_measurements_files[i]) {
> > + algo_idx = i;
> > + algo = ima_tpm_chip->allocated_banks[i].crypto_id;
> > + break;
> > + }
> > + }
> > + }
> >
> > /* get entry */
> > e = qe->entry;
> > @@ -151,7 +170,7 @@ int ima_measurements_show(struct seq_file *m, void *v)
> > ima_putc(m, &pcr, sizeof(e->pcr));
> >
> > /* 2nd: template digest */
> > - ima_putc(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
> > + ima_putc(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
> >
> > /* 3rd: template name size */
> > namelen = !ima_canonical_fmt ? strlen(template_name) :
> > @@ -220,7 +239,23 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
> > struct ima_queue_entry *qe = v;
> > struct ima_template_entry *e;
> > char *template_name;
> > - int i;
> > + struct dentry *dentry;
> > + int i, algo_idx;
> > + enum hash_algo algo;
> > +
> > + dentry = m->file->f_path.dentry;
>
> Same.
>
> > + algo_idx = ima_sha1_idx;
> > + algo = HASH_ALGO_SHA1;
> > +
> > + if (ima_tpm_chip) {
> > + for (i = 0; i < NR_BANKS(ima_tpm_chip); i++) {
> > + if (dentry == ima_ascii_measurements_files[i]) {
>
> Uhm, why not iterating over ima_ascii_measurements_files?
>
> But I have another comment on this.
>
> Have a look at ima_crypto.c:
>
> if (ima_sha1_idx < 0) {
> ima_sha1_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++;
> if (ima_hash_algo == HASH_ALGO_SHA1)
> ima_hash_algo_idx = ima_sha1_idx;
> }
>
> This is done because not necessarily the TPM has a SHA1 bank.
>
> ima_extra_slots is already exported, you could use that to determine if
> you need more slots than NR_BANKS(ima_tpm_chip).
>
> > + algo_idx = i;
> > + algo = ima_tpm_chip->allocated_banks[i].crypto_id;
> > + break;
> > + }
> > + }
> > + }
> >
> > /* get entry */
> > e = qe->entry;
> > @@ -233,8 +268,8 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v)
> > /* 1st: PCR used (config option) */
> > seq_printf(m, "%2d ", e->pcr);
> >
> > - /* 2nd: SHA1 template hash */
> > - ima_print_digest(m, e->digests[ima_sha1_idx].digest, TPM_DIGEST_SIZE);
> > + /* 2nd: template hash */
> > + ima_print_digest(m, e->digests[algo_idx].digest, hash_digest_size[algo]);
> >
> > /* 3th: template name */
> > seq_printf(m, " %s", template_name);
> > @@ -379,6 +414,84 @@ static const struct seq_operations ima_policy_seqops = {
> > };
> > #endif
> >
> > +/*
> > + * Remove the securityfs files created for each hash algo configured
> > + * in the TPM, excluded ascii_runtime_measurements and
> > + * binary_runtime_measurements.
> > + */
>
> It does not hurt following the kernel-doc format.
>
> > +static void remove_measurements_list_files(struct dentry **files)
> > +{
> > + int i, len;
> > + len = ima_tpm_chip ? NR_BANKS(ima_tpm_chip) : 1;
>
> It is much better having a global variable with the number of array
> elements.
>
> > +
> > + if (files)
> > + {
>
> This bracket should be one line up.
>
> > + for (i = 0; i < len; i++) {
> > + if (files[i]) {
> > + securityfs_remove(files[i]);
> > + }
> > + }
> > +
> > + kfree(files);
> > + }
> > +}
> > +
> > +/*
> > + * Allocate a file in the securityfs for each hash algo configured
> > + * in the TPM (for ascii and binary output). In case no TPM chip is
> > + * detected only sha1 files are created.
> > + */
> > +static int create_measurements_list_files(void)
> > +{
> > + int i, len;
> > + u16 algo;
> > + char file_name[NAME_MAX+1];
> > + struct dentry *dfile;
> > +
> > + /*
> > + * Allocate NR_BANKS(ima_tpm_chip) files in case a tpm chip is detected,
> > + * otherwise allocate just one file for sha1.
> > + */
> > + len = ima_tpm_chip ? NR_BANKS(ima_tpm_chip) : 1;
>
> See the comment above regarding ima_extra_slots.
>
> If you export len (static), you can always use that without extra
> logic.
>
> > +
> > + ima_ascii_measurements_files = kmalloc_array(len,
> > + sizeof(struct dentry *), GFP_KERNEL);
> > + if(!ima_ascii_measurements_files)
> > + return -ENOMEM;
> > +
> > + ima_binary_measurements_files = kmalloc_array(len,
> > + sizeof(struct dentry *), GFP_KERNEL);
> > + if(!ima_binary_measurements_files)
> > + return -ENOMEM;
> > +
> > + for (i = 0; i < len; i++) {
> > + algo = ima_tpm_chip ? ima_tpm_chip->allocated_banks[i].crypto_id :
> > + HASH_ALGO_SHA1;
>
> I'm starting to think that maybe we should export ima_algo_array
> instead, and follow that.
>
> > +
> > + sprintf(file_name, "ascii_runtime_measurements_%s",
> > + hash_algo_name[algo]);
> > + dfile = securityfs_create_file(file_name,
> > + S_IRUSR | S_IRGRP, ima_dir, NULL,
> > + &ima_ascii_measurements_ops);
> > + if (IS_ERR(dfile))
> > + return PTR_ERR(dfile);
> > +
> > + ima_ascii_measurements_files[i] = dfile;
> > +
> > + sprintf(file_name, "binary_runtime_measurements_%s",
> > + hash_algo_name[algo]);
> > + dfile = securityfs_create_file(file_name,
> > + S_IRUSR | S_IRGRP, ima_dir, NULL,
> > + &ima_measurements_ops);
> > + if (IS_ERR(dfile))
> > + return PTR_ERR(dfile);
> > +
> > + ima_binary_measurements_files[i] = dfile;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > /*
> > * ima_open_policy: sequentialize access to the policy file
> > */
> > @@ -465,19 +578,21 @@ int __init ima_fs_init(void)
> > goto out;
> > }
> >
> > - binary_runtime_measurements =
> > - securityfs_create_file("binary_runtime_measurements",
> > - S_IRUSR | S_IRGRP, ima_dir, NULL,
> > - &ima_measurements_ops);
> > + ret = create_measurements_list_files();
> > + if (ret != 0)
> > + goto out;
> > +
> > + binary_runtime_measurements = securityfs_create_symlink(
> > + "binary_runtime_measurements", ima_dir,
> > + "binary_runtime_measurements_sha1", NULL);
> > if (IS_ERR(binary_runtime_measurements)) {
> > ret = PTR_ERR(binary_runtime_measurements);
> > goto out;
> > }
> >
> > - ascii_runtime_measurements =
> > - securityfs_create_file("ascii_runtime_measurements",
> > - S_IRUSR | S_IRGRP, ima_dir, NULL,
> > - &ima_ascii_measurements_ops);
> > + ascii_runtime_measurements = securityfs_create_symlink(
> > + "ascii_runtime_measurements", ima_dir,
> > + "ascii_runtime_measurements_sha1", NULL);
> > if (IS_ERR(ascii_runtime_measurements)) {
> > ret = PTR_ERR(ascii_runtime_measurements);
> > goto out;
> > @@ -515,6 +630,8 @@ int __init ima_fs_init(void)
> > securityfs_remove(runtime_measurements_count);
> > securityfs_remove(ascii_runtime_measurements);
> > securityfs_remove(binary_runtime_measurements);
> > + remove_measurements_list_files(ima_ascii_measurements_files);
> > + remove_measurements_list_files(ima_binary_measurements_files);
>
> The rest is ok.
>
> Thanks
>
> Roberto
>
> > securityfs_remove(ima_symlink);
> > securityfs_remove(ima_dir);
> >
> > base-commit: 88035e5694a86a7167d490bb95e9df97a9bb162b
prev parent reply other threads:[~2024-01-25 8:49 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-24 19:32 [PATCH v3] ima: add crypto agility support for template-hash algorithm Enrico Bravi
2024-01-25 8:30 ` Roberto Sassu
2024-01-25 8:49 ` Roberto Sassu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ec47723ee4712458dea2810820a05c301c1137d2.camel@huaweicloud.com \
--to=roberto.sassu@huaweicloud.com \
--cc=enrico.bravi@polito.it \
--cc=linux-integrity@vger.kernel.org \
--cc=roberto.sassu@huawei.com \
--cc=silvia.sisinni@polito.it \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).