@@ -230,6 +230,7 @@ enum tpm2_command_codes {
TPM2_CC_CONTEXT_LOAD = 0x0161,
TPM2_CC_CONTEXT_SAVE = 0x0162,
TPM2_CC_FLUSH_CONTEXT = 0x0165,
+ TPM2_CC_POLICY_AUTHVALUE = 0x016B,
TPM2_CC_POLICY_COUNTER_TIMER = 0x016D,
TPM2_CC_START_AUTH_SESS = 0x0176,
TPM2_CC_VERIFY_SIGNATURE = 0x0177,
@@ -240,6 +241,7 @@ enum tpm2_command_codes {
TPM2_CC_PCR_EXTEND = 0x0182,
TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
TPM2_CC_HASH_SEQUENCE_START = 0x0186,
+ TPM2_CC_POLICY_PASSWORD = 0x018c,
TPM2_CC_CREATE_LOADED = 0x0191,
TPM2_CC_LAST = 0x0193, /* Spec 1.36 */
};
@@ -67,6 +67,7 @@ static int tpm2_validate_policy(struct tpm2_policies *pols)
switch (pols->code[i]) {
case TPM2_CC_POLICY_COUNTER_TIMER:
case TPM2_CC_POLICY_PCR:
+ case TPM2_CC_POLICY_AUTHVALUE:
break;
default:
pr_warn("tpm2 policy 0x%x is unsupported",
@@ -198,7 +199,8 @@ int tpm2_generate_policy_digest(struct tpm2_policies *pols,
len = *plen;
}
- crypto_shash_update(sdesc, policy, len);
+ if (len)
+ crypto_shash_update(sdesc, policy, len);
/* now output the intermediate to the policydigest */
crypto_shash_final(sdesc, policydigest);
@@ -334,6 +336,16 @@ int tpm2_get_policy_session(struct tpm_chip *chip, struct tpm2_policies *pols,
u32 cmd = pols->code[i];
struct tpm_buf buf;
+ if (cmd == TPM2_CC_POLICY_AUTHVALUE)
+ /*
+ * both PolicyAuthValue and PolicyPassword
+ * hash to the same thing, but one triggers
+ * HMAC authentication and the other simple
+ * authentication. Since we have no HMAC
+ * code, we're choosing the simple
+ */
+ cmd = TPM2_CC_POLICY_PASSWORD;
+
rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, cmd);
if (rc)
return rc;
@@ -294,6 +294,39 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
return -EINVAL;
}
+ /*
+ * if we already have a policy, we have to add authorization
+ * to it. If we don't, we can simply follow the usual
+ * non-policy route.
+ */
+ if (options->blobauth_len != 0 && payload->policies) {
+ struct tpm2_policies *pols;
+ static u8 *scratch;
+ int i;
+ bool found = false;
+
+ pols = payload->policies;
+
+ /* make sure it's not already in policy */
+ for (i = 0; i < pols->count; i++) {
+ if (pols->code[i] == TPM2_CC_POLICY_AUTHVALUE) {
+ found = true;
+
+ break;
+ }
+ }
+
+ if (!found) {
+ i = pols->count++;
+ scratch = pols->policies[i - 1] + pols->len[i - 1];
+
+ /* the TPM2_PolicyPassword command has no payload */
+ pols->policies[i] = scratch;
+ pols->len[i] = 0;
+ pols->code[i] = TPM2_CC_POLICY_AUTHVALUE;
+ }
+ }
+
if (payload->policies) {
rc = tpm2_generate_policy_digest(payload->policies,
options->hash,
When using authorizations (passwords) with a policy, the trigger for the authorizations must be present in the policy statements that are required to build to the policy hash. Add this required policy statement if blobauth is present. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> --- include/linux/tpm.h | 2 ++ security/keys/trusted-keys/tpm2-policy.c | 14 +++++++++- security/keys/trusted-keys/trusted_tpm2.c | 33 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-)