From: James Bottomley <James.Bottomley@HansenPartnership.com> To: linux-integrity@vger.kernel.org Cc: Mimi Zohar <zohar@linux.ibm.com>, Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>, David Woodhouse <dwmw2@infradead.org>, keyrings@vger.kernel.org Subject: [PATCH v6 5/6] security: keys: trusted: add ability to specify arbitrary policy Date: Mon, 02 Mar 2020 12:27:58 +0000 [thread overview] Message-ID: <20200302122759.5204-6-James.Bottomley@HansenPartnership.com> (raw) In-Reply-To: <20200302122759.5204-1-James.Bottomley@HansenPartnership.com> This patch adds a policy= argument to key creation. The policy is the standard tss policymaker format and each separate policy line must have a newline after it. Thus to construct a policy requiring authorized value and pcr 16 locking using a sha256 hash, the policy (policy.txt) file would be two lines: 0000017F00000001000B03000001303095B49BE85E381E5B20E557E46363EF55B0F43B132C2D8E3DE9AC436656F2 0000016b This can be inserted into the key with keyctl add trusted kmk "new 32 policy=`cat policy.txt` keyhandle=0x81000001 hash=sha256" @u Note that although a few policies work like this, most require special handling which must be added to the kernel policy construction routine. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> --- Documentation/security/keys/trusted-encrypted.rst | 16 +++++++ security/keys/trusted-keys/tpm2-policy.c | 53 +++++++++++++++++++++++ security/keys/trusted-keys/tpm2-policy.h | 1 + security/keys/trusted-keys/trusted_tpm1.c | 15 +++++++ 4 files changed, 85 insertions(+) diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst index 053344c4df5b..b68d3eb73f00 100644 --- a/Documentation/security/keys/trusted-encrypted.rst +++ b/Documentation/security/keys/trusted-encrypted.rst @@ -76,6 +76,9 @@ Usage:: 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. + policy= specify an arbitrary set of policies. These must + be in policymaker format with each separate + policy line newline terminated. "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. @@ -168,6 +171,19 @@ zeros (the value of PCR 16):: $ dd if=/dev/zero bs=1 count 2>/dev/null|sha1sum 6768033e216468247bd031a0a2d9876d79818f8f +You can also specify arbitrary policy in policymaker format, so a two +value policy (the pcr example above and authvalue) would look like +this in policymaker format:: + + 0000017F000000010004030000016768033e216468247bd031a0a2d9876d79818f8f + 0000016b + +This can be placed in a file (say policy.txt) and then added to the key as:: + + $ keyctl add trusted kmk "new 32 keyhandle=0x81000001 hash=sha1 policy=`cat policy.txt`" @u + +The newlines in the file policy.txt will be automatically processed. + Reseal a trusted key under new pcr values:: $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`" diff --git a/security/keys/trusted-keys/tpm2-policy.c b/security/keys/trusted-keys/tpm2-policy.c index de07e576c9f4..4cc478feaeb1 100644 --- a/security/keys/trusted-keys/tpm2-policy.c +++ b/security/keys/trusted-keys/tpm2-policy.c @@ -370,3 +370,56 @@ int tpm2_get_policy_session(struct tpm_chip *chip, struct tpm2_policies *pols, return 0; } + +int tpm2_parse_policies(struct tpm2_policies **ppols, char *str) +{ + struct tpm2_policies *pols; + char *p; + u8 *ptr; + int i = 0, left = PAGE_SIZE, res; + + pols = kmalloc(left, GFP_KERNEL); + if (!pols) + return -ENOMEM; + + ptr = (u8 *)(pols + 1); + left -= ptr - (u8 *)pols; + + while ((p = strsep(&str, "\n"))) { + if (*p = '\0' || *p = '\n') + continue; + + pols->len[i] = strlen(p)/2; + if (pols->len[i] > left) { + res = -E2BIG; + goto err; + } + + res = hex2bin(ptr, p, pols->len[i]); + if (res) + goto err; + + /* get command code and skip past */ + pols->code[i] = get_unaligned_be32(ptr); + pols->policies[i] = ptr + 4; + ptr += pols->len[i]; + left -= pols->len[i]; + pols->len[i] -= 4; + + /* + * FIXME: this does leave the code embedded in dead + * regions of the memory, but it's easier than + * hexdumping to a temporary or copying over + */ + i++; + } + + pols->count = i; + *ppols = pols; + + return 0; + + err: + kfree(pols); + return res; +} diff --git a/security/keys/trusted-keys/tpm2-policy.h b/security/keys/trusted-keys/tpm2-policy.h index 152c948743f3..cb804a544ced 100644 --- a/security/keys/trusted-keys/tpm2-policy.h +++ b/security/keys/trusted-keys/tpm2-policy.h @@ -28,3 +28,4 @@ int tpm2_generate_policy_digest(struct tpm2_policies *pols, u32 hash, int tpm2_encode_policy(struct tpm2_policies *pols, u8 **data, u32 *len); int tpm2_get_policy_session(struct tpm_chip *chip, struct tpm2_policies *pols, u32 *handle); +int tpm2_parse_policies(struct tpm2_policies **ppols, char *str); diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c index 08e7bb89f7bf..242181c6304b 100644 --- a/security/keys/trusted-keys/trusted_tpm1.c +++ b/security/keys/trusted-keys/trusted_tpm1.c @@ -29,6 +29,8 @@ #include <keys/trusted_tpm.h> +#include "tpm2-policy.h" + static const char hmac_alg[] = "hmac(sha1)"; static const char hash_alg[] = "sha1"; static struct tpm_chip *chip; @@ -709,6 +711,7 @@ enum { Opt_hash, Opt_policydigest, Opt_policyhandle, + Opt_policy, }; static const match_table_t key_tokens = { @@ -724,6 +727,7 @@ static const match_table_t key_tokens = { {Opt_hash, "hash=%s"}, {Opt_policydigest, "policydigest=%s"}, {Opt_policyhandle, "policyhandle=%s"}, + {Opt_policy, "policy=%s"}, {Opt_err, NULL} }; @@ -854,6 +858,17 @@ static int getoptions(char *c, struct trusted_key_payload *pay, return -EINVAL; opt->policyhandle = handle; break; + + case Opt_policy: + if (pay->policies) + return -EINVAL; + if (!tpm2) + return -EINVAL; + res = tpm2_parse_policies(&pay->policies, args[0].from); + if (res) + return res; + break; + default: return -EINVAL; } -- 2.16.4
WARNING: multiple messages have this Message-ID (diff)
From: James Bottomley <James.Bottomley@HansenPartnership.com> To: linux-integrity@vger.kernel.org Cc: Mimi Zohar <zohar@linux.ibm.com>, Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>, David Woodhouse <dwmw2@infradead.org>, keyrings@vger.kernel.org Subject: [PATCH v6 5/6] security: keys: trusted: add ability to specify arbitrary policy Date: Mon, 2 Mar 2020 07:27:58 -0500 [thread overview] Message-ID: <20200302122759.5204-6-James.Bottomley@HansenPartnership.com> (raw) In-Reply-To: <20200302122759.5204-1-James.Bottomley@HansenPartnership.com> This patch adds a policy= argument to key creation. The policy is the standard tss policymaker format and each separate policy line must have a newline after it. Thus to construct a policy requiring authorized value and pcr 16 locking using a sha256 hash, the policy (policy.txt) file would be two lines: 0000017F00000001000B03000001303095B49BE85E381E5B20E557E46363EF55B0F43B132C2D8E3DE9AC436656F2 0000016b This can be inserted into the key with keyctl add trusted kmk "new 32 policy=`cat policy.txt` keyhandle=0x81000001 hash=sha256" @u Note that although a few policies work like this, most require special handling which must be added to the kernel policy construction routine. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> --- Documentation/security/keys/trusted-encrypted.rst | 16 +++++++ security/keys/trusted-keys/tpm2-policy.c | 53 +++++++++++++++++++++++ security/keys/trusted-keys/tpm2-policy.h | 1 + security/keys/trusted-keys/trusted_tpm1.c | 15 +++++++ 4 files changed, 85 insertions(+) diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst index 053344c4df5b..b68d3eb73f00 100644 --- a/Documentation/security/keys/trusted-encrypted.rst +++ b/Documentation/security/keys/trusted-encrypted.rst @@ -76,6 +76,9 @@ Usage:: 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. + policy= specify an arbitrary set of policies. These must + be in policymaker format with each separate + policy line newline terminated. "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. @@ -168,6 +171,19 @@ zeros (the value of PCR 16):: $ dd if=/dev/zero bs=1 count=20 2>/dev/null|sha1sum 6768033e216468247bd031a0a2d9876d79818f8f +You can also specify arbitrary policy in policymaker format, so a two +value policy (the pcr example above and authvalue) would look like +this in policymaker format:: + + 0000017F000000010004030000016768033e216468247bd031a0a2d9876d79818f8f + 0000016b + +This can be placed in a file (say policy.txt) and then added to the key as:: + + $ keyctl add trusted kmk "new 32 keyhandle=0x81000001 hash=sha1 policy=`cat policy.txt`" @u + +The newlines in the file policy.txt will be automatically processed. + Reseal a trusted key under new pcr values:: $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`" diff --git a/security/keys/trusted-keys/tpm2-policy.c b/security/keys/trusted-keys/tpm2-policy.c index de07e576c9f4..4cc478feaeb1 100644 --- a/security/keys/trusted-keys/tpm2-policy.c +++ b/security/keys/trusted-keys/tpm2-policy.c @@ -370,3 +370,56 @@ int tpm2_get_policy_session(struct tpm_chip *chip, struct tpm2_policies *pols, return 0; } + +int tpm2_parse_policies(struct tpm2_policies **ppols, char *str) +{ + struct tpm2_policies *pols; + char *p; + u8 *ptr; + int i = 0, left = PAGE_SIZE, res; + + pols = kmalloc(left, GFP_KERNEL); + if (!pols) + return -ENOMEM; + + ptr = (u8 *)(pols + 1); + left -= ptr - (u8 *)pols; + + while ((p = strsep(&str, "\n"))) { + if (*p == '\0' || *p == '\n') + continue; + + pols->len[i] = strlen(p)/2; + if (pols->len[i] > left) { + res = -E2BIG; + goto err; + } + + res = hex2bin(ptr, p, pols->len[i]); + if (res) + goto err; + + /* get command code and skip past */ + pols->code[i] = get_unaligned_be32(ptr); + pols->policies[i] = ptr + 4; + ptr += pols->len[i]; + left -= pols->len[i]; + pols->len[i] -= 4; + + /* + * FIXME: this does leave the code embedded in dead + * regions of the memory, but it's easier than + * hexdumping to a temporary or copying over + */ + i++; + } + + pols->count = i; + *ppols = pols; + + return 0; + + err: + kfree(pols); + return res; +} diff --git a/security/keys/trusted-keys/tpm2-policy.h b/security/keys/trusted-keys/tpm2-policy.h index 152c948743f3..cb804a544ced 100644 --- a/security/keys/trusted-keys/tpm2-policy.h +++ b/security/keys/trusted-keys/tpm2-policy.h @@ -28,3 +28,4 @@ int tpm2_generate_policy_digest(struct tpm2_policies *pols, u32 hash, int tpm2_encode_policy(struct tpm2_policies *pols, u8 **data, u32 *len); int tpm2_get_policy_session(struct tpm_chip *chip, struct tpm2_policies *pols, u32 *handle); +int tpm2_parse_policies(struct tpm2_policies **ppols, char *str); diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c index 08e7bb89f7bf..242181c6304b 100644 --- a/security/keys/trusted-keys/trusted_tpm1.c +++ b/security/keys/trusted-keys/trusted_tpm1.c @@ -29,6 +29,8 @@ #include <keys/trusted_tpm.h> +#include "tpm2-policy.h" + static const char hmac_alg[] = "hmac(sha1)"; static const char hash_alg[] = "sha1"; static struct tpm_chip *chip; @@ -709,6 +711,7 @@ enum { Opt_hash, Opt_policydigest, Opt_policyhandle, + Opt_policy, }; static const match_table_t key_tokens = { @@ -724,6 +727,7 @@ static const match_table_t key_tokens = { {Opt_hash, "hash=%s"}, {Opt_policydigest, "policydigest=%s"}, {Opt_policyhandle, "policyhandle=%s"}, + {Opt_policy, "policy=%s"}, {Opt_err, NULL} }; @@ -854,6 +858,17 @@ static int getoptions(char *c, struct trusted_key_payload *pay, return -EINVAL; opt->policyhandle = handle; break; + + case Opt_policy: + if (pay->policies) + return -EINVAL; + if (!tpm2) + return -EINVAL; + res = tpm2_parse_policies(&pay->policies, args[0].from); + if (res) + return res; + break; + default: return -EINVAL; } -- 2.16.4
next prev parent reply other threads:[~2020-03-02 12:27 UTC|newest] Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-03-02 12:27 [PATCH v6 0/6] TPM 2.0 trusted keys with attached policy James Bottomley 2020-03-02 12:27 ` James Bottomley 2020-03-02 12:27 ` [PATCH v6 1/6] lib: add ASN.1 encoder James Bottomley 2020-03-02 12:27 ` James Bottomley 2020-03-03 19:22 ` Jarkko Sakkinen 2020-03-03 19:22 ` Jarkko Sakkinen 2020-03-03 20:49 ` James Bottomley 2020-03-03 20:49 ` James Bottomley 2020-03-03 21:31 ` Jarkko Sakkinen 2020-03-03 21:31 ` Jarkko Sakkinen 2020-03-02 12:27 ` [PATCH v6 2/6] oid_registry: Add TCG defined OIDS for TPM keys James Bottomley 2020-03-02 12:27 ` James Bottomley 2020-03-03 19:24 ` Jarkko Sakkinen 2020-03-03 19:24 ` Jarkko Sakkinen 2020-03-02 12:27 ` [PATCH v6 3/6] security: keys: trusted: fix TPM2 authorizations James Bottomley 2020-03-02 12:27 ` James Bottomley 2020-03-03 19:33 ` Jarkko Sakkinen 2020-03-03 19:33 ` Jarkko Sakkinen 2020-03-03 20:39 ` James Bottomley 2020-03-03 20:39 ` James Bottomley 2020-03-03 21:32 ` Jarkko Sakkinen 2020-03-03 21:32 ` Jarkko Sakkinen 2020-03-02 12:27 ` [PATCH v6 4/6] security: keys: trusted: use ASN.1 TPM2 key format for the blobs James Bottomley 2020-03-02 12:27 ` James Bottomley 2020-03-03 20:06 ` Jarkko Sakkinen 2020-03-03 20:06 ` Jarkko Sakkinen 2020-03-03 20:42 ` James Bottomley 2020-03-03 20:42 ` James Bottomley 2020-03-03 21:20 ` Jarkko Sakkinen 2020-03-03 21:20 ` Jarkko Sakkinen 2020-03-02 12:27 ` James Bottomley [this message] 2020-03-02 12:27 ` [PATCH v6 5/6] security: keys: trusted: add ability to specify arbitrary policy James Bottomley 2020-03-02 12:27 ` [PATCH v6 6/6] security: keys: trusted: implement counter/timer policy James Bottomley 2020-03-02 12:27 ` James Bottomley 2020-03-03 20:08 ` Jarkko Sakkinen 2020-03-03 20:08 ` Jarkko Sakkinen 2020-03-03 20:40 ` James Bottomley 2020-03-03 20:40 ` James Bottomley 2020-03-03 21:20 ` Jarkko Sakkinen 2020-03-03 21:20 ` 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=20200302122759.5204-6-James.Bottomley@HansenPartnership.com \ --to=james.bottomley@hansenpartnership.com \ --cc=dwmw2@infradead.org \ --cc=jarkko.sakkinen@linux.intel.com \ --cc=keyrings@vger.kernel.org \ --cc=linux-integrity@vger.kernel.org \ --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: linkBe 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.