Message ID | 1446306824-25175-1-git-send-email-jarkko.sakkinen@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sat, 2015-10-31 at 17:53 +0200, Jarkko Sakkinen wrote: > Support for sealing with a policy. > > Two new options for trusted keys: > > * 'policydigest=': provide a policydigest for the seal operation. > * 'policyhandle=': provide handle for a policy session for unsealing. Please expand the patch description explaining the motivation for these new options. In what cases are they needed? Are they system or session policies? Mimi > > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > --- > drivers/char/tpm/Kconfig | 1 + > drivers/char/tpm/tpm2-cmd.c | 20 +++++++++++++++++--- > include/keys/trusted-type.h | 3 +++ > security/keys/trusted.c | 26 ++++++++++++++++++++++++-- > 4 files changed, 45 insertions(+), 5 deletions(-) > > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig > index 3b84a8b..bd86261 100644 > --- a/drivers/char/tpm/Kconfig > +++ b/drivers/char/tpm/Kconfig > @@ -6,6 +6,7 @@ menuconfig TCG_TPM > tristate "TPM Hardware Support" > depends on HAS_IOMEM > select SECURITYFS > + select CRYPTO_HASH_INFO > ---help--- > If you have a TPM security chip in your system, which > implements the Trusted Computing Group's specification, > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c > index b08a0b4..6f567c3 100644 > --- a/drivers/char/tpm/tpm2-cmd.c > +++ b/drivers/char/tpm/tpm2-cmd.c > @@ -463,6 +463,9 @@ int tpm2_seal_trusted(struct tpm_chip *chip, > return -EINVAL; > } > > + if (options->policydigest_len > hash_digest_size[options->hash]) > + return -EINVAL; > + > rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); > if (rc) > return rc; > @@ -488,8 +491,17 @@ int tpm2_seal_trusted(struct tpm_chip *chip, > > 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 */ > + > + if (options->policydigest_len) { > + tpm_buf_append_u32(&buf, 0); > + tpm_buf_append_u16(&buf, options->policydigest_len); > + tpm_buf_append(&buf, options->policydigest, > + options->policydigest_len); > + } else { > + tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); > + tpm_buf_append_u16(&buf, 0); > + } > + > tpm_buf_append_u16(&buf, TPM2_ALG_NULL); > tpm_buf_append_u16(&buf, 0); > > @@ -617,7 +629,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..e4beeca 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 policydigest_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 7a87bcd..ea043ff 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} > }; > > @@ -804,6 +808,17 @@ static int getoptions(char *c, struct trusted_key_payload *pay, > if (i == HASH_ALGO__LAST || > (!res && i != HASH_ALGO_SHA1)) > return -EINVAL; > + case Opt_policydigest: > + opt->policydigest_len = strlen(args[0].from); > + opt->policydigest = kstrdup(args[0].from, GFP_KERNEL); > + if (!opt->policydigest) > + return -ENOMEM; > + break; > + case Opt_policyhandle: > + res = kstrtoul(args[0].from, 16, &handle); > + if (res < 0) > + return -EINVAL; > + opt->policyhandle = handle; > break; > default: > return -EINVAL; > @@ -897,6 +912,13 @@ static struct trusted_key_options *trusted_options_alloc(void) > return options; > } > > +static void trusted_options_free(struct trusted_key_options *options) > +{ > + if (options->policydigest) > + kfree(options->policydigest); > + kfree(options); > +} > + > static struct trusted_key_payload *trusted_payload_alloc(struct key *key) > { > struct trusted_key_payload *p = NULL; > @@ -1003,7 +1025,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 > @@ -1091,7 +1113,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; > } > ------------------------------------------------------------------------------
On Mon, Nov 02, 2015 at 07:48:42AM -0500, Mimi Zohar wrote: > On Sat, 2015-10-31 at 17:53 +0200, Jarkko Sakkinen wrote: > > Support for sealing with a policy. > > > > Two new options for trusted keys: > > > > * 'policydigest=': provide a policydigest for the seal operation. > > * 'policyhandle=': provide handle for a policy session for unsealing. > > Please expand the patch description explaining the motivation for these > new options. In what cases are they needed? Are they system or session > policies? They are session policies. By using TPM2 commands you can specify conditions in which unseal should work like auth value, PCRs, localities and so forth and combine these with logical connectors. I'll think about this and write proper documentation. > Mimi /Jarkko ------------------------------------------------------------------------------
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 3b84a8b..bd86261 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -6,6 +6,7 @@ menuconfig TCG_TPM tristate "TPM Hardware Support" depends on HAS_IOMEM select SECURITYFS + select CRYPTO_HASH_INFO ---help--- If you have a TPM security chip in your system, which implements the Trusted Computing Group's specification, diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index b08a0b4..6f567c3 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -463,6 +463,9 @@ int tpm2_seal_trusted(struct tpm_chip *chip, return -EINVAL; } + if (options->policydigest_len > hash_digest_size[options->hash]) + return -EINVAL; + rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); if (rc) return rc; @@ -488,8 +491,17 @@ int tpm2_seal_trusted(struct tpm_chip *chip, 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 */ + + if (options->policydigest_len) { + tpm_buf_append_u32(&buf, 0); + tpm_buf_append_u16(&buf, options->policydigest_len); + tpm_buf_append(&buf, options->policydigest, + options->policydigest_len); + } else { + tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); + tpm_buf_append_u16(&buf, 0); + } + tpm_buf_append_u16(&buf, TPM2_ALG_NULL); tpm_buf_append_u16(&buf, 0); @@ -617,7 +629,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..e4beeca 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 policydigest_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 7a87bcd..ea043ff 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} }; @@ -804,6 +808,17 @@ static int getoptions(char *c, struct trusted_key_payload *pay, if (i == HASH_ALGO__LAST || (!res && i != HASH_ALGO_SHA1)) return -EINVAL; + case Opt_policydigest: + opt->policydigest_len = strlen(args[0].from); + opt->policydigest = kstrdup(args[0].from, GFP_KERNEL); + if (!opt->policydigest) + return -ENOMEM; + break; + case Opt_policyhandle: + res = kstrtoul(args[0].from, 16, &handle); + if (res < 0) + return -EINVAL; + opt->policyhandle = handle; break; default: return -EINVAL; @@ -897,6 +912,13 @@ static struct trusted_key_options *trusted_options_alloc(void) return options; } +static void trusted_options_free(struct trusted_key_options *options) +{ + if (options->policydigest) + kfree(options->policydigest); + kfree(options); +} + static struct trusted_key_payload *trusted_payload_alloc(struct key *key) { struct trusted_key_payload *p = NULL; @@ -1003,7 +1025,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 @@ -1091,7 +1113,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; }
Support for sealing with a policy. Two new options for trusted keys: * 'policydigest=': provide a policydigest for the seal operation. * 'policyhandle=': provide handle for a policy session for unsealing. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- drivers/char/tpm/Kconfig | 1 + drivers/char/tpm/tpm2-cmd.c | 20 +++++++++++++++++--- include/keys/trusted-type.h | 3 +++ security/keys/trusted.c | 26 ++++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 5 deletions(-)