82ab887bba
- Update the TPM2 patches to skip the persistent SRK handle if not specified and improve the error messages + 0003-protectors-Add-TPM2-Key-Protector.patch + 0005-util-grub-protect-Add-new-tool.patch + 0004-tpm2-Support-authorized-policy.patch OBS-URL: https://build.opensuse.org/request/show/1127240 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=475
171 lines
5.6 KiB
Diff
171 lines
5.6 KiB
Diff
From 542c4fc6e067e04e8b96f798882ae968c59f4948 Mon Sep 17 00:00:00 2001
|
|
From: Gary Lin <glin@suse.com>
|
|
Date: Thu, 6 Apr 2023 16:00:25 +0800
|
|
Subject: [PATCH v7 16/20] 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 --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>
|
|
---
|
|
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 df0727215..0cbfd06e8 100644
|
|
--- a/grub-core/tpm2/module.c
|
|
+++ b/grub-core/tpm2/module.c
|
|
@@ -453,6 +453,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)
|
|
{
|
|
@@ -472,6 +553,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
|
|
|