diff mbox series

[v9,6/6] IMA: Read keyrings= option from the IMA policy

Message ID 20191127015654.3744-7-nramas@linux.microsoft.com (mailing list archive)
State New, archived
Headers show
Series KEYS: Measure keys when they are created or updated | expand

Commit Message

Lakshmi Ramasubramanian Nov. 27, 2019, 1:56 a.m. UTC
Read "keyrings=" option, if specified in the IMA policy, and store in
the list of IMA rules when the configured IMA policy is read.

This patch defines a new policy token enum namely Opt_keyrings
and an option flag IMA_KEYRINGS for reading "keyrings=" option
from the IMA policy.

Updated ima_parse_rule() to parse "keyrings=" option in the policy.
Updated ima_policy_show() to display "keyrings=" option.

The following example illustrates how key measurement can be verified.

Sample IMA Policy entry to measure keys
(Added in the file /etc/ima/ima-policy):
measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf

Build the kernel with this patch set applied and reboot to that kernel.

Ensure the IMA policy is applied:

root@nramas:/home/nramas# cat /sys/kernel/security/ima/policy
measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf

View the initial IMA measurement log:

root@nramas:/home/nramas# cat /sys/kernel/security/ima/ascii_runtime_measurements
10 67ec... ima-ng sha1:b5466c508583f0e633df83aa58fc7c5b67ccf667 boot_aggregate

Now, add a certificate (for example, x509_ima.der) to the .ima keyring
using evmctl (IMA-EVM Utility)

root@nramas:/home/nramas# keyctl show %:.ima
Keyring
 547515640 ---lswrv      0     0  keyring: .ima

root@nramas:/home/nramas# evmctl import x509_ima.der 547515640

root@nramas:/home/nramas# keyctl show %:.ima
Keyring
 547515640 ---lswrv      0     0  keyring: .ima
 809678766 --als--v      0     0   \_ asymmetric: hostname: whoami signing key: 052dd247dc3c36...

View the updated IMA measurement log:

root@nramas:/home/nramas# cat /sys/kernel/security/ima/ascii_runtime_measurements
10 67ec... ima-ng sha1:b5466c508583f0e633df83aa58fc7c5b67ccf667 boot_aggregate
10 3adf... ima-buf sha256:27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b .ima 308202863082...4aee
root@nramas:/home/nramas#

For this sample, SHA256 should be selected as the hash algorithm
used by IMA.

The following command verifies if the SHA256 hash generated from
the payload in the IMA log entry (listed above) for the .ima key
matches the SHA256 hash in the IMA log entry. The output of this
command should match the SHA256 hash given in the IMA log entry
(In this case, it should be 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b)

root@nramas:/home/nramas# cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b | cut -d' ' -f 6 | xxd -r -p |tee ima-cert.der | sha256sum | cut -d' ' -f 1

The above command also creates a binary file namely ima-cert.der
using the payload in the IMA log entry. This file should be a valid
x509 certificate which can be verified using openssl as given below:

root@nramas:/home/nramas# openssl x509 -in ima-cert.der -inform DER -text

The above command should display the contents of the file ima-cert.der
as an x509 certificate.

The IMA policy used here allows measurement of keys added to
".ima" and ".evm" keyrings only. Add a key to any other keyring and
verify that the key is not measured.

Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
---
 security/integrity/ima/ima_policy.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

Comments

Mimi Zohar Nov. 27, 2019, 7:32 p.m. UTC | #1
On Tue, 2019-11-26 at 17:56 -0800, Lakshmi Ramasubramanian wrote:
> Read "keyrings=" option, if specified in the IMA policy, and store in
> the list of IMA rules when the configured IMA policy is read.
> 
> This patch defines a new policy token enum namely Opt_keyrings
> and an option flag IMA_KEYRINGS for reading "keyrings=" option
> from the IMA policy.
> 
> Updated ima_parse_rule() to parse "keyrings=" option in the policy.
> Updated ima_policy_show() to display "keyrings=" option.
> 
> The following example illustrates how key measurement can be verified.

The example is really too colloquial/verbose.  Please truncate it,
leaving just a sample "key" policy rule, with directions for verifying
the template data against the digest included in the measurement list.

> 
> Sample IMA Policy entry to measure keys
> (Added in the file /etc/ima/ima-policy):

Remove the above.

Sample "key" measurement rule:

> measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf
> 
> Build the kernel with this patch set applied and reboot to that kernel.
> 
> Ensure the IMA policy is applied:
> 
> root@nramas:/home/nramas# cat /sys/kernel/security/ima/policy
> measure func=KEY_CHECK keyrings=.ima|.evm template=ima-buf
> 
> View the initial IMA measurement log:
> 
> root@nramas:/home/nramas
> # cat /sys/kernel/security/ima/ascii_runtime_measurements
> 10 67ec... ima-ng sha1:b5466c508583f0e633df83aa58fc7c5b67ccf667 boot_aggregate
> 
> Now, add a certificate (for example, x509_ima.der) to the .ima keyring
> using evmctl (IMA-EVM Utility)
> 
> root@nramas:/home/nramas# keyctl show %:.ima
> Keyring
>  547515640 ---lswrv      0     0  keyring: .ima
> 
> root@nramas:/home/nramas# evmctl import x509_ima.der 547515640
> 
> root@nramas:/home/nramas# keyctl show %:.ima
> Keyring
>  547515640 ---lswrv      0     0  keyring: .ima
>  809678766 --als--v      0     0   \_ asymmetric: hostname: whoami signing key: 052dd247dc3c36...
> 
> View the updated IMA measurement log:
> 
> root@nramas:/home/nramas#

Remove everything up to here and simply say something like:

Display "key" measurement in the IMA measurement list:

> # cat /sys/kernel/security/ima/ascii_runtime_measurements

> 10 3adf... ima-buf
> sha256:27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3
> b7b .ima 308202863082...4aee


> root@nramas:/home/nramas#

Remove this string from all the commands.
> 
> For this sample, SHA256 should be selected as the hash algorithm
> used by IMA.
> 
> The following command verifies if the SHA256 hash generated from
> the payload in the IMA log entry (listed above) for the .ima key
> matches the SHA256 hash in the IMA log entry. The output of this
> command should match the SHA256 hash given in the IMA log entry
> (In this case, it should be
> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b)

Previously you didn't use the hash value, but ".ima" to locate the
"key" measurement in the measurement list.  In each of the commands
above, it might be clearer.

> 
> root@nramas:/home/nramas

ditto

> # cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements
> | grep
> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b | 

> cut -d' ' -f 6 | xxd -r -p |tee ima-cert.der | sha256sum | cut -d' '
> -f 1
> 
> The above command also creates a binary file namely ima-cert.der
> using the payload in the IMA log entry. This file should be a valid
> x509 certificate which can be verified using openssl as given below:
> 
> root@nramas:/home/nramas

ditto


> # openssl x509 -in ima-cert.der -inform DER -text
> 
> The above command should display the contents of the file ima-cert.der
> as an x509 certificate.

Either the comments should be above or below the commands, not both.

> 
> The IMA policy used here allows measurement of keys added to
> ".ima" and ".evm" keyrings only. Add a key to any other keyring and
> verify that the key is not measured.

This comment would be included, if desired, when defining the policy
rule, not here.

Mimi
Lakshmi Ramasubramanian Nov. 27, 2019, 10:05 p.m. UTC | #2
On 11/27/19 11:32 AM, Mimi Zohar wrote:

> 
> The example is really too colloquial/verbose.  Please truncate it,
> leaving just a sample "key" policy rule, with directions for verifying
> the template data against the digest included in the measurement list.

I'll truncate the example and keep it to the point.

>> The following command verifies if the SHA256 hash generated from
>> the payload in the IMA log entry (listed above) for the .ima key
>> matches the SHA256 hash in the IMA log entry. The output of this
>> command should match the SHA256 hash given in the IMA log entry
>> (In this case, it should be
>> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b)
> 
> Previously you didn't use the hash value, but ".ima" to locate the
> "key" measurement in the measurement list.  In each of the commands
> above, it might be clearer.

If the IMA measurement list has only one IMA key then locating it with 
".ima" would work - hash won't be needed for locating the entry.

But for describing key verification we can have just one IMA key. I'll 
change the description to locate the entry using ".ima".

>> # cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements
>> | grep
>> 27c915b8ddb9fae7214cf0a8a7043cc3eeeaa7539bcb136f8427067b5f6c3b7b |
> 
>> cut -d' ' -f 6 | xxd -r -p |tee ima-cert.der | sha256sum | cut -d' '
>> -f 1
>>
>> The above command also creates a binary file namely ima-cert.der
>> using the payload in the IMA log entry. This file should be a valid
>> x509 certificate which can be verified using openssl as given below:
>>
>> root@nramas:/home/nramas
> 
> ditto
> 
> 
>> # openssl x509 -in ima-cert.der -inform DER -text
>>
>> The above command should display the contents of the file ima-cert.der
>> as an x509 certificate.
> 
> Either the comments should be above or below the commands, not both.

I'll update the comment.

> 
>>
>> The IMA policy used here allows measurement of keys added to
>> ".ima" and ".evm" keyrings only. Add a key to any other keyring and
>> verify that the key is not measured.
> 
> This comment would be included, if desired, when defining the policy
> rule, not here.

Will remove the above from this patch description.

thanks,
  -lakshmi
diff mbox series

Patch

diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d9400585fcda..78b25f083fe1 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -34,6 +34,7 @@ 
 #define IMA_EUID	0x0080
 #define IMA_PCR		0x0100
 #define IMA_FSNAME	0x0200
+#define IMA_KEYRINGS	0x0400
 
 #define UNKNOWN		0
 #define MEASURE		0x0001	/* same as IMA_MEASURE */
@@ -825,7 +826,8 @@  enum {
 	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
 	Opt_appraise_type, Opt_appraise_flag,
-	Opt_permit_directio, Opt_pcr, Opt_template, Opt_err
+	Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
+	Opt_err
 };
 
 static const match_table_t policy_tokens = {
@@ -861,6 +863,7 @@  static const match_table_t policy_tokens = {
 	{Opt_permit_directio, "permit_directio"},
 	{Opt_pcr, "pcr=%s"},
 	{Opt_template, "template=%s"},
+	{Opt_keyrings, "keyrings=%s"},
 	{Opt_err, NULL}
 };
 
@@ -1110,6 +1113,23 @@  static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			result = 0;
 			entry->flags |= IMA_FSNAME;
 			break;
+		case Opt_keyrings:
+			ima_log_string(ab, "keyrings", args[0].from);
+
+			if ((entry->keyrings) ||
+			    (entry->action != MEASURE) ||
+			    (entry->func != KEY_CHECK)) {
+				result = -EINVAL;
+				break;
+			}
+			entry->keyrings = kstrdup(args[0].from, GFP_KERNEL);
+			if (!entry->keyrings) {
+				result = -ENOMEM;
+				break;
+			}
+			result = 0;
+			entry->flags |= IMA_KEYRINGS;
+			break;
 		case Opt_fsuuid:
 			ima_log_string(ab, "fsuuid", args[0].from);
 
@@ -1485,6 +1505,13 @@  int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, " ");
 	}
 
+	if (entry->flags & IMA_KEYRINGS) {
+		if (entry->keyrings != NULL)
+			snprintf(tbuf, sizeof(tbuf), "%s", entry->keyrings);
+		seq_printf(m, pt(Opt_keyrings), tbuf);
+		seq_puts(m, " ");
+	}
+
 	if (entry->flags & IMA_PCR) {
 		snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr);
 		seq_printf(m, pt(Opt_pcr), tbuf);