All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
To: Peter Huewe <peterhuewe@gmx.de>,
	Marcel Selhorst <tpmdd@selhorst.net>,
	David Howells <dhowells@redhat.com>
Cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>,
	Mimi Zohar <zohar@linux.vnet.ibm.com>,
	David Safford <safford@us.ibm.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Jason Gunthorpe <jgunthorpe@obsidianresearch.com>,
	James Morris <james.l.morris@oracle.com>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	linux-security-module@vger.kernel.org (open list:KEYS-ENCRYPTED),
	keyrings@vger.kernel.org (open list:KEYS-ENCRYPTED),
	linux-doc@vger.kernel.org (open list:DOCUMENTATION),
	linux-kernel@vger.kernel.org (open list),
	tpmdd-devel@lists.sourceforge.net (moderated list:TPM DEVICE
	DRIVER)
Subject: [PATCH 2/2] keys, trusted: seal with a policy
Date: Tue, 17 Nov 2015 18:27:22 +0200	[thread overview]
Message-ID: <1447777643-10777-3-git-send-email-jarkko.sakkinen@linux.intel.com> (raw)
In-Reply-To: <1447777643-10777-1-git-send-email-jarkko.sakkinen@linux.intel.com>

Support for sealing with a authorization policy.

Two new options for trusted keys:

* 'policydigest=': provide an auth policy digest for sealing.
* 'policyhandle=': provide a policy session handle for unsealing.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 Documentation/security/keys-trusted-encrypted.txt | 34 ++++++++++-------
 drivers/char/tpm/tpm2-cmd.c                       | 24 ++++++++++--
 include/keys/trusted-type.h                       |  3 ++
 security/keys/trusted.c                           | 46 ++++++++++++++++++++++-
 4 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/Documentation/security/keys-trusted-encrypted.txt b/Documentation/security/keys-trusted-encrypted.txt
index fd2565b..324ddf5 100644
--- a/Documentation/security/keys-trusted-encrypted.txt
+++ b/Documentation/security/keys-trusted-encrypted.txt
@@ -27,20 +27,26 @@ Usage:
     keyctl print keyid
 
     options:
-       keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
-       keyauth=	  ascii hex auth for sealing key default 0x00...i
-		  (40 ascii zeros)
-       blobauth=  ascii hex auth for sealed data default 0x00...
-		  (40 ascii zeros)
-       blobauth=  ascii hex auth for sealed data default 0x00...
-		  (40 ascii zeros)
-       pcrinfo=	  ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
-       pcrlock=	  pcr number to be extended to "lock" blob
-       migratable= 0|1 indicating permission to reseal to new PCR values,
-                   default 1 (resealing allowed)
-       hash=      hash algorithm name as a string. For TPM 1.x the only
-                  allowed value is sha1. For TPM 2.x the allowed values
-		  are sha1, sha256, sha384, sha512 and sm3-256.
+       keyhandle=    ascii hex value of sealing key default 0x40000000 (SRK)
+       keyauth=	     ascii hex auth for sealing key default 0x00...i
+                     (40 ascii zeros)
+       blobauth=     ascii hex auth for sealed data default 0x00...
+                     (40 ascii zeros)
+       blobauth=     ascii hex auth for sealed data default 0x00...
+                     (40 ascii zeros)
+       pcrinfo=	     ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
+       pcrlock=	     pcr number to be extended to "lock" blob
+       migratable=   0|1 indicating permission to reseal to new PCR values,
+                     default 1 (resealing allowed)
+       hash=         hash algorithm name as a string. For TPM 1.x the only
+                     allowed value is sha1. For TPM 2.x the allowed values
+                     are sha1, sha256, sha384, sha512 and sm3-256.
+       policydigest= digest for the authorization policy. must be calculated
+                     with the same hash algorithm as specified by the 'hash='
+                     option.
+       policyhandle= handle to an authorization policy session that defines the
+                     same policy and with the same hash algorithm as was used to
+                     seal the key.
 
 "keyctl print" returns an ascii hex copy of the sealed key, which is in standard
 TPM_STORED_DATA format.  The key length for new keys are always in bytes.
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index d9d0822..45a6340 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -478,12 +478,26 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 	tpm_buf_append_u8(&buf, payload->migratable);
 
 	/* public */
-	tpm_buf_append_u16(&buf, 14);
+	if (options->policydigest)
+		tpm_buf_append_u16(&buf, 14 + options->digest_len);
+	else
+		tpm_buf_append_u16(&buf, 14);
 
 	tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH);
 	tpm_buf_append_u16(&buf, hash);
-	tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
-	tpm_buf_append_u16(&buf, 0); /* policy digest size */
+
+	/* policy */
+	if (options->policydigest) {
+		tpm_buf_append_u32(&buf, 0);
+		tpm_buf_append_u16(&buf, options->digest_len);
+		tpm_buf_append(&buf, options->policydigest,
+			       options->digest_len);
+	} else {
+		tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
+		tpm_buf_append_u16(&buf, 0);
+	}
+
+	/* public parameters */
 	tpm_buf_append_u16(&buf, TPM2_ALG_NULL);
 	tpm_buf_append_u16(&buf, 0);
 
@@ -613,7 +627,9 @@ static int tpm2_unseal(struct tpm_chip *chip,
 		return rc;
 
 	tpm_buf_append_u32(&buf, blob_handle);
-	tpm2_buf_append_auth(&buf, TPM2_RS_PW,
+	tpm2_buf_append_auth(&buf,
+			     options->policyhandle ?
+			     options->policyhandle : TPM2_RS_PW,
 			     NULL /* nonce */, 0,
 			     0 /* session_attributes */,
 			     options->blobauth /* hmac */,
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index a6a1008..2c3f9f7 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -37,6 +37,9 @@ struct trusted_key_options {
 	unsigned char pcrinfo[MAX_PCRINFO_SIZE];
 	int pcrlock;
 	uint32_t hash;
+	uint32_t digest_len;
+	unsigned char *policydigest;
+	uint32_t policyhandle;
 };
 
 extern struct key_type key_type_trusted;
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index b5b0a55..b726a83 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -713,6 +713,8 @@ enum {
 	Opt_keyhandle, Opt_keyauth, Opt_blobauth,
 	Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
 	Opt_hash,
+	Opt_policydigest,
+	Opt_policyhandle,
 };
 
 static const match_table_t key_tokens = {
@@ -726,6 +728,8 @@ static const match_table_t key_tokens = {
 	{Opt_pcrlock, "pcrlock=%s"},
 	{Opt_migratable, "migratable=%s"},
 	{Opt_hash, "hash=%s"},
+	{Opt_policydigest, "policydigest=%s"},
+	{Opt_policyhandle, "policyhandle=%s"},
 	{Opt_err, NULL}
 };
 
@@ -739,6 +743,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 	int res;
 	unsigned long handle;
 	unsigned long lock;
+	unsigned int policydigest_len;
 	int i;
 	int tpm2;
 
@@ -747,6 +752,8 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 		return tpm2;
 
 	opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1;
+	opt->digest_len = hash_digest_size[opt->hash];
+	policydigest_len = opt->digest_len;
 
 	while ((p = strsep(&c, " \t"))) {
 		if (*p == '\0' || *p == ' ' || *p == '\t')
@@ -802,6 +809,8 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 			for (i = 0; i < HASH_ALGO__LAST; i++) {
 				if (!strcmp(args[0].from, hash_algo_name[i])) {
 					opt->hash = i;
+					opt->digest_len =
+						hash_digest_size[opt->hash];
 					break;
 				}
 			}
@@ -812,10 +821,37 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 				return -EINVAL;
 			}
 			break;
+		case Opt_policydigest:
+			if (!tpm2 ||
+			    strlen(args[0].from) != (2 * opt->digest_len))
+				return -EINVAL;
+			kfree(opt->policydigest);
+			opt->policydigest = kzalloc(opt->digest_len,
+						    GFP_KERNEL);
+			if (!opt->policydigest)
+				return -ENOMEM;
+			res = hex2bin(opt->policydigest, args[0].from,
+				      opt->digest_len);
+			if (res < 0)
+				return -EINVAL;
+			policydigest_len = opt->digest_len;
+			break;
+		case Opt_policyhandle:
+			if (!tpm2)
+				return -EINVAL;
+			res = kstrtoul(args[0].from, 16, &handle);
+			if (res < 0)
+				return -EINVAL;
+			opt->policyhandle = handle;
+			break;
 		default:
 			return -EINVAL;
 		}
 	}
+
+	if (opt->policydigest && policydigest_len != opt->digest_len)
+		return -EINVAL;
+
 	return 0;
 }
 
@@ -904,6 +940,12 @@ static struct trusted_key_options *trusted_options_alloc(void)
 	return options;
 }
 
+static void trusted_options_free(struct trusted_key_options *options)
+{
+	kfree(options->policydigest);
+	kfree(options);
+}
+
 static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
 {
 	struct trusted_key_payload *p = NULL;
@@ -1010,7 +1052,7 @@ static int trusted_instantiate(struct key *key,
 		ret = pcrlock(options->pcrlock);
 out:
 	kfree(datablob);
-	kfree(options);
+	trusted_options_free(options);
 	if (!ret)
 		rcu_assign_keypointer(key, payload);
 	else
@@ -1098,7 +1140,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
 	call_rcu(&p->rcu, trusted_rcu_free);
 out:
 	kfree(datablob);
-	kfree(new_o);
+	trusted_options_free(new_o);
 	return ret;
 }
 
-- 
2.5.0


  parent reply	other threads:[~2015-11-17 16:27 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-17 16:27 [PATCH 0/2] TPM 2.0 trusted key features for v4.5 Jarkko Sakkinen
2015-11-17 16:27 ` Jarkko Sakkinen
2015-11-17 16:27 ` [PATCH 1/2] keys, trusted: select hash algorithm for TPM2 chips Jarkko Sakkinen
2015-11-17 16:27   ` Jarkko Sakkinen
2015-11-17 16:27 ` Jarkko Sakkinen [this message]
2015-11-18  0:21   ` [PATCH 2/2] keys, trusted: seal with a policy James Morris
2015-11-18  7:03     ` Jarkko Sakkinen
2015-11-20  2:34       ` James Morris
2015-12-07  9:12         ` Jarkko Sakkinen
2015-12-07 22:35           ` James Morris
2015-12-08 11:01             ` Jarkko Sakkinen
2015-12-08 20:24               ` Jarkko Sakkinen
2015-12-08 23:56                 ` Mimi Zohar
2015-12-09 14:24                   ` Jarkko Sakkinen
2015-12-09 16:10                     ` Mimi Zohar
2015-11-19 10:59   ` [tpmdd-devel] " Fuchs, Andreas
2015-11-20 14:53     ` Jarkko Sakkinen
2015-11-21 18:50   ` Jarkko Sakkinen
2015-11-23 14:49   ` Jarkko Sakkinen

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=1447777643-10777-3-git-send-email-jarkko.sakkinen@linux.intel.com \
    --to=jarkko.sakkinen@linux.intel.com \
    --cc=corbet@lwn.net \
    --cc=dhowells@redhat.com \
    --cc=james.l.morris@oracle.com \
    --cc=jgunthorpe@obsidianresearch.com \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=peterhuewe@gmx.de \
    --cc=safford@us.ibm.com \
    --cc=serge@hallyn.com \
    --cc=tpmdd-devel@lists.sourceforge.net \
    --cc=tpmdd@selhorst.net \
    --cc=zohar@linux.vnet.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.