- Update to the latest upstreaming TPM2 patches * 0001-key_protector-Add-key-protectors-framework.patch - Replace 0001-protectors-Add-key-protectors-framework.patch * 0002-tpm2-Add-TPM-Software-Stack-TSS.patch - Merge other TSS patches * 0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch * 0002-tpm2-Add-more-marshal-unmarshal-functions.patch * 0003-tpm2-Implement-more-TPM2-commands.patch * 0003-key_protector-Add-TPM2-Key-Protector.patch - Replace 0003-protectors-Add-TPM2-Key-Protector.patch * 0004-cryptodisk-Support-key-protectors.patch * 0005-util-grub-protect-Add-new-tool.patch * 0001-tpm2-Support-authorized-policy.patch - Replace 0004-tpm2-Support-authorized-policy.patch * 0001-tpm2-Add-extra-RSA-SRK-types.patch * 0001-tpm2-Implement-NV-index.patch - Replace 0001-protectors-Implement-NV-index.patch * 0002-cryptodisk-Fallback-to-passphrase.patch * 0003-cryptodisk-wipe-out-the-cached-keys-from-protectors.patch * 0004-diskfilter-look-up-cryptodisk-devices-first.patch - Refresh affected patches * 0001-Improve-TPM-key-protection-on-boot-interruptions.patch * grub2-bsc1220338-key_protector-implement-the-blocklist.patch - New manpage for grub2-protect OBS-URL: https://build.opensuse.org/request/show/1174325 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=504
172 lines
5.7 KiB
Diff
172 lines
5.7 KiB
Diff
From 26a66098d5fa50b9462c8c815429a4c18f20310b Mon Sep 17 00:00:00 2001
|
|
From: Gary Lin <glin@suse.com>
|
|
Date: Thu, 6 Apr 2023 16:00:25 +0800
|
|
Subject: [PATCH] tpm2: Support authorized policy
|
|
|
|
This commit handles the TPM2_PolicyAuthorize command from the key file
|
|
in TPM 2.0 Key File format.
|
|
|
|
TPM2_PolicyAuthorize is the essential command to support authorized
|
|
policy which allows the users to sign TPM policies with their own keys.
|
|
Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize
|
|
comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and
|
|
'TPMT_SIGNATURE signature'. To verify the signature, the current policy
|
|
digest is hashed with the hash algorithm written in 'signature', and then
|
|
'signature' is verified with the hashed policy digest and 'pubkey'. Once
|
|
TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the
|
|
signed policy.
|
|
|
|
To create the key file with authorized policy, here are the pcr-oracle(*2)
|
|
commands:
|
|
|
|
# Generate the RSA key and create the authorized policy file
|
|
$ pcr-oracle \
|
|
--rsa-generate-key \
|
|
--private-key policy-key.pem \
|
|
--auth authorized.policy \
|
|
create-authorized-policy 0,2,4,7,9
|
|
|
|
# Seal the secret with the authorized policy
|
|
$ pcr-oracle \
|
|
--key-format tpm2.0 \
|
|
--auth authorized.policy \
|
|
--input disk-secret.txt \
|
|
--output sealed.key \
|
|
seal-secret
|
|
|
|
# Sign the predicted PCR policy
|
|
$ pcr-oracle \
|
|
--key-format tpm2.0 \
|
|
--private-key policy-key.pem \
|
|
--from eventlog \
|
|
--stop-event "grub-file=grub.cfg" \
|
|
--after \
|
|
--input sealed.key \
|
|
--output sealed.tpm \
|
|
sign 0,2,4,7,9
|
|
|
|
Then specify the key file and the key protector to grub.cfg in the EFI
|
|
system partition:
|
|
|
|
tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
|
|
cryptomount -u <PART_UUID> -P tpm2
|
|
|
|
For any change in the boot components, just run the 'sign' command again
|
|
to update the signature in sealed.tpm, and TPM can unseal the key file
|
|
with the updated PCR policy.
|
|
|
|
(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
|
|
(*2) https://github.com/okirch/pcr-oracle
|
|
|
|
Signed-off-by: Gary Lin <glin@suse.com>
|
|
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
|
---
|
|
grub-core/tpm2/module.c | 84 +++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 84 insertions(+)
|
|
|
|
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
|
index 3db25ceca..e83b02865 100644
|
|
--- a/grub-core/tpm2/module.c
|
|
+++ b/grub-core/tpm2/module.c
|
|
@@ -650,6 +650,87 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session,
|
|
return GRUB_ERR_NONE;
|
|
}
|
|
|
|
+static grub_err_t
|
|
+grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session,
|
|
+ struct grub_tpm2_buffer *cmd_buf)
|
|
+{
|
|
+ TPM2B_PUBLIC pubkey;
|
|
+ TPM2B_DIGEST policy_ref;
|
|
+ TPMT_SIGNATURE signature;
|
|
+ TPM2B_DIGEST pcr_policy;
|
|
+ TPM2B_DIGEST pcr_policy_hash;
|
|
+ TPMI_ALG_HASH sig_hash;
|
|
+ TPMT_TK_VERIFIED verification_ticket;
|
|
+ TPM_HANDLE pubkey_handle = 0;
|
|
+ TPM2B_NAME pubname;
|
|
+ TPM_RC rc;
|
|
+ grub_err_t err;
|
|
+
|
|
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
|
|
+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
|
|
+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
|
|
+ if (cmd_buf->error != 0)
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
+ N_("Failed to unmarshal the buffer for TPM2_PolicyAuthorize"));
|
|
+
|
|
+ /* Retrieve Policy Digest */
|
|
+ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL);
|
|
+ if (rc != TPM_RC_SUCCESS)
|
|
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
|
+ N_("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x)."),
|
|
+ rc);
|
|
+
|
|
+ /* Calculate the digest of the polcy for VerifySignature */
|
|
+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
|
|
+ if (sig_hash == TPM_ALG_NULL)
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
+ N_("Failed to get the hash algorithm of the signature"));
|
|
+
|
|
+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash,
|
|
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
|
|
+ if (rc != TPM_RC_SUCCESS)
|
|
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
|
+ N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"),
|
|
+ rc);
|
|
+
|
|
+ /* Load the public key */
|
|
+ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER,
|
|
+ &pubkey_handle, &pubname, NULL);
|
|
+ if (rc != TPM_RC_SUCCESS)
|
|
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
|
+ N_("Failed to load public key (TPM2_LoadExternal: 0x%x)"),
|
|
+ rc);
|
|
+
|
|
+ /* Verify the signature against the public key and the policy digest */
|
|
+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
|
|
+ &verification_ticket, NULL);
|
|
+ if (rc != TPM_RC_SUCCESS)
|
|
+ {
|
|
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
|
+ N_("Failed to verify signature (TPM2_VerifySignature: 0x%x)"),
|
|
+ rc);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ /* Authorize the signed policy with the public key and the verification ticket */
|
|
+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
|
|
+ &verification_ticket, NULL);
|
|
+ if (rc != TPM_RC_SUCCESS)
|
|
+ {
|
|
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
|
+ N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)"),
|
|
+ rc);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ err = GRUB_ERR_NONE;
|
|
+
|
|
+error:
|
|
+ TPM2_FlushContext (pubkey_handle);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
static grub_err_t
|
|
grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session)
|
|
{
|
|
@@ -669,6 +750,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
|
|
case TPM_CC_PolicyPCR:
|
|
err = grub_tpm2_protector_policypcr (session, &buf);
|
|
break;
|
|
+ case TPM_CC_PolicyAuthorize:
|
|
+ err = grub_tpm2_protector_policyauthorize (session, &buf);
|
|
+ break;
|
|
default:
|
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
|
|
--
|
|
2.35.3
|
|
|