git: https://github.com/lcp/grub2/tree/tpm2-follow-up-v4
This patchset is the collection of several enhancements for TPM2 key protector. * Patch 1 introduces the PCR dump to help debugging policy fail. * Patch 2 adds the new command to dump PCRs in GRUB shell and the * documentation of the command. * Patch 3 fixes a minor issue in tss2. * Patch 4~7 extend the NV index mode to support 'NV index' handles and TPM 2.0 Key File format. - Thanks to James Bottomley for how to detect TPM 2.0 Key File format. https://lists.gnu.org/archive/html/grub-devel/2024-11/msg00078.html * Patch 8~11 update the test cases and the documentation for NV index mode. * Patch 12 documents the external packages needed for TPM2 key protector tests. v4: - Updating the commit messages and the documentation - Merging the tpm2_dump_pcr documentation patch - Splitting the testcase patch into 3 smaller patches - Documenting the extern packages needed for TPM2 key protector tests v3: - Amending the function names to make them more comprehensive - Fixing a few more typos and the indentations - Improving the document v2: - Amending the commit messages and the error messages - Fixing the return values and the checks for 'bool' - Removing 'policywrite' when defining the NV index handle - Fixing the typo and the stray whitespace - Removing grub_tpm2_flushcontext() from the functions to remove the persistent handle and the NV index handle - Avoiding one failure test case to stop the whole test - Improving the document Gary Lin (12): tpm2_key_protector: dump PCRs on policy fail tpm2_key_protector: Add 'tpm2_dump_pcr' command tss2: Fix the missing authCommand tss2: Add TPM 2.0 NV index commands tpm2_key_protector: Unseal key from a buffer tpm2_key_protector: Support NV index handles util/grub-protect: Support NV index mode tests/tpm2_key_protector_test: Simplify the NV index mode test tests/tpm2_key_protector_test: Reset 'ret' on fail tests/tpm2_key_protector_test: Add more NV index mode tests docs: Update NV index mode of TPM2 key protector INSTALL: Document the packages needed for TPM2 key protector tests INSTALL | 1 + docs/grub.texi | 214 +++++++++-- .../commands/tpm2_key_protector/module.c | 345 +++++++++++++++--- grub-core/lib/tss2/tpm2_cmd.c | 211 ++++++++++- grub-core/lib/tss2/tpm2_cmd.h | 32 ++ grub-core/lib/tss2/tss2_mu.c | 39 ++ grub-core/lib/tss2/tss2_mu.h | 12 + grub-core/lib/tss2/tss2_types.h | 6 + tests/tpm2_key_protector_test.in | 155 +++----- util/grub-protect.c | 343 ++++++++++++++--- 10 files changed, 1120 insertions(+), 238 deletions(-) Range-diff against v3: 1: cf2be1c66 ! 1: bbd534f6b tpm2_key_protector: dump PCRs on policy fail @@ Commit message The sample output: - PCR Mismatching! Check firmware and bootloader before typing passphrase! + PCR Mismatch! Check firmware and bootloader before typing passphrase! TPM PCR [sha256]: - 00: 115c89bfa0e59e050cda5d2664031d225305f3582cf0c2afcb7c1f1ac2a7cf8d - 01: 079b3eadca25e10248daea4b1d508e5cfb703db28386be809a0b375c0a0a80a5 - 02: 2cd8ec3de6a07e1fd39676100db57ba62372e820c19812fee55899f65746e192 - 03: 9423b585d4eac05c97a0c06bca8898ad0ca519a6b810dcb91129bcdc10f4b112 - 04: fa36bf5c9110d3891f040e2146d157484cd41123fa8faf4bc6b91db3d12b70ca - 05: 13e9ea9e38e5258e6ee2b6ae94a3cece0137490ef95c65caaac10cdf5e1bc40d - 06: 3ac10d749054a818806788f4e4eaa2fb4dd7d13ce0e99dc175145b63c34bb71c - 07: a6657a60f77928cad614a7ad153ab9ae0bed48e33b70348ae11a26762002b3bc - 08: 42e04f5bac1965535cb6bdb30c62bb199b1ba21d1ec6b22d0da159dfc925b8bb - 09: 5c83e8be79d4a432e6d409610de389ee6f1ac0c193f38d84a9ff94f360bd458b + 00: 17401f37710984c1d8a03a81fff3ab567ae9291bac61e21715b890ee28879738 + 01: 7a114329ba388445a96e8db2a072785937c1b7a8803ed7cc682b87f3ff3dd7a8 + 02: 11c2776849e8e24b7d80c926cbc4257871bffa744dadfefd3ed049ce25143e05 + 03: 6c33b362073e28e30b47302bbdd3e6f9cee4debca3a304e646f8c68245724350 + 04: 62d38838483ecfd2484ee3a2e5450d8ca3b35fc72cda6a8c620f9f43521c37d1 + 05: d8a85cb37221ab7d1f2cc5f554dbe0463acb6784b5b8dc3164ccaa66d8fff0e1 + 06: 9262e37cbe71ed4daf815b4a4881fb7251c9d371092dde827557d5368121e10e + 07: 219d542233be492d62b079ffe46cf13396a8c27e520e88b08eaf2e6d3b7e70f5 + 08: de1f61c973b673e505adebe0d7e8fb65fde6c24dd4ab4fbaff9e28b18df6ecd3 + 09: c1de7274fa3e879a16d7e6e7629e3463d95f68adcfd17c477183846dccc41c89 10: 0000000000000000000000000000000000000000000000000000000000000000 11: 0000000000000000000000000000000000000000000000000000000000000000 12: 0000000000000000000000000000000000000000000000000000000000000000 13: 0000000000000000000000000000000000000000000000000000000000000000 - 14: 894dd8e4ca1bb62e055f674f9390a39c4643ebdd1014702feef000c47e36a003 + 14: 9ab9ebe4879a7f4dd00c04f37e79cfd69d0dd7a8bcc6b01135525b67676a3e40 15: 0000000000000000000000000000000000000000000000000000000000000000 16: 0000000000000000000000000000000000000000000000000000000000000000 17: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff @@ Commit message Signed-off-by: Gary Lin <g...@suse.com> Reviewed-by: Stefan Berger <stef...@linux.ibm.com> + Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> ## grub-core/commands/tpm2_key_protector/module.c ## @@ grub-core/commands/tpm2_key_protector/module.c: tpm2_protector_simple_policy_seq (const tpm2_protector_context_t *ctx, 2: 052089a84 ! 2: a0c949ba8 tpm2_key_protector: Add 'tpm2_dump_pcr' command @@ Commit message so the new 'tpm2_dump_pcr' command is added to print all PCRs of the specified bank. + Also update the document for the new command. + Signed-off-by: Gary Lin <g...@suse.com> Tested-by: Stefan Berger <stef...@linux.ibm.com> + Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> + + ## docs/grub.texi ## +@@ docs/grub.texi: you forget a command, you can run the command @command{help} + * test:: Check file types and compare values + * tpm2_key_protector_init:: Initialize the TPM2 key protector + * tpm2_key_protector_clear:: Clear the TPM2 key protector ++* tpm2_dump_pcr:: Dump TPM2 PCRs + * true:: Do nothing, successfully + * trust:: Add public key to list of trusted keys + * unset:: Unset an environment variable +@@ docs/grub.texi: key and unseal it with the given PCR list and bank. + Clear the TPM2 key protector if previously initialized. + @end deffn + ++@node tpm2_dump_pcr ++@subsection tpm2_dump_pcr ++ ++@deffn Command tpm2_dump_pcr [@var{bank}] ++Print all PCRs of the specified TPM 2.0 @var{bank}. The supported banks are ++@samp{sha1}, @samp{sha256}, @samp{sha384}, and @samp{sha512}. If @var{bank} ++is not specified, @samp{sha256} is chosen by default. ++ ++Since GRUB measures every command into PCR 8, invoking @command{tpm2_dump_pcr} ++also extends PCR 8, so PCR 8 will not be a stable value in GRUB shell. ++@end deffn ++ + @node true + @subsection true + ## grub-core/commands/tpm2_key_protector/module.c ## @@ grub-core/commands/tpm2_key_protector/module.c: static grub_extcmd_t tpm2_protector_init_cmd; 3: 01f27df8a < -: --------- docs: Document tpm2_dump_pcr 4: 242483c87 ! 3: bbd4ad377 tss2: Fix the missing authCommand @@ Commit message Signed-off-by: Gary Lin <g...@suse.com> Reviewed-by: Stefan Berger <stef...@linux.ibm.com> + Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> ## grub-core/lib/tss2/tpm2_cmd.c ## @@ grub-core/lib/tss2/tpm2_cmd.c: grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle, 5: 3f0aca8af = 4: d2fba3963 tss2: Add TPM 2.0 NV index commands 6: 733b8c507 ! 5: 9b7ebc818 tpm2_key_protector: Unseal key from a buffer @@ Commit message tpm2_key_protector: Unseal key from a buffer Extract the logic to handle the file buffer from the SRK recover - function to prepare to load the sealed key from the NV index handle. + function to prepare to load the sealed key from the NV index handle, + so the NV index mode can share the same code path in the later patch. The SRK recover function now only reads the file and sends the file - buffer to the new function. Besides this, the file format is detected - automatically before unmarshalling the data, so there is no need to use - the command option to specify the file format anymore. In other words, - '--tpm2key' and '--keyfile' are the same now. + buffer to the new function. + + Besides this, to avoid introducing more options for the NV index mode, + the file format is detected automatically before unmarshalling the data, + so there is no need to use the command option to specify the file format + anymore. In other words, '--tpm2key' and '--keyfile' are the same now. + + Also update grub.text to address the change. Signed-off-by: Gary Lin <g...@suse.com> Reviewed-by: Stefan Berger <stef...@linux.ibm.com> + ## docs/grub.texi ## +@@ docs/grub.texi: options are @option{-T}, @option{-k}, @option{-a}, and @option{-s}. On the + other hand, the NV index-specific option is @option{-n}. + + The key file for SRK mode can be supplied with either @option{-T} or +-@option{-k}. The @option{-T} option is for the path to the key file in +-TPM 2.0 Key File format. Since the parameters for the TPM commands are written +-in the file, there is no need to set the PCR list(@option{-p}) and +-bank(@option{-b}) when using the @option{-T} option. The @option{-k} option +-is for the key file in the raw format, and the @option{-p} and @option{-b} +-options are necessary for the non-default PCR list or bank. In general, ++@option{-k}. Those two options were used to distinguish the file formats but ++are same now. There are two supported file formats: raw format and TPM 2.0 ++Key File format. When using the key file in the raw format, the @option{-p} ++and @option{-b} options are necessary for the non-default PCR list or bank. ++On the other hand, when using the key file in TPM 2.0 Key File format, the ++the parameters for the TPM commands are written in the file, and there is no ++need to set the PCR list(@option{-p}) and bank(@option{-b}). In general, + TPM 2.0 Key File format is preferred due to the simplified GRUB command + options and the authorized policy support + + ## grub-core/commands/tpm2_key_protector/module.c ## @@ grub-core/commands/tpm2_key_protector/module.c: tpm2_protector_srk_read_file (const char *filepath, void **buffer, grub_size_t * return err; 7: b92cfb4b0 ! 6: c78c78763 tpm2_key_protector: Support NV index handles @@ Commit message # tpm2_nvundefine -C o 0x1000000 Signed-off-by: Gary Lin <g...@suse.com> + Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com> ## grub-core/commands/tpm2_key_protector/module.c ## @@ grub-core/commands/tpm2_key_protector/module.c: tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx, 8: be4d93cb2 ! 7: 10eb6a6b0 util/grub-protect: Support NV index mode @@ Commit message types of TPM handles. 1. Persistent handle (0x81000000~0x81FFFFFF) - TPM 2.0 Key File format (--tpm2key) is not supported due to the - limitation of persistent handles. This 'grub-protect' command - seals the key into the persistent handle 0x81000000. + Only the raw format is supported due to the limitation of persistent + handles. This 'grub-protect' command seals the key into the + persistent handle 0x81000000. # grub-protect \ --protector=tpm2 \ @@ Commit message --tpm2-evict \ --tpm2-nvindex=0x1000000 + Also set and check the boolean variables with true/false instead of 1/0. + Signed-off-by: Gary Lin <g...@suse.com> Reviewed-by: Stefan Berger <stef...@linux.ibm.com> 9: 15bce58ed ! 8: 3d5836268 tests/tpm2_key_protector_test: Amend the NV index mode test @@ Metadata Author: Gary Lin <g...@suse.com> ## Commit message ## - tests/tpm2_key_protector_test: Amend the NV index mode test + tests/tpm2_key_protector_test: Simplify the NV index mode test Since 'grub-protect' already supports NV index mode, tpm2_seal_nv() is replaced with one 'grub-protect' command to simplify the test script. - Two more NV index test cases are also added to test key sealing and - unsealing with the NV index handle 0x1000000. - - Also, there is a minor fix to reset 'ret' to 0 when a test case fails so - that the other test cases could continue. + 'tpm2_evictcontrol' is also replaced with 'grub-protect --tpm2-evict'. Signed-off-by: Gary Lin <g...@suse.com> - Reviewed-by: Stefan Berger <stef...@linux.ibm.com> ## tests/tpm2_key_protector_test.in ## @@ tests/tpm2_key_protector_test.in: EOF @@ tests/tpm2_key_protector_test.in: EOF - echo "Failed to flush the transient handles: ${ret}" >&2 - return 1 - fi -+tpm2_seal_unseal_nv() { -+ handle_type="$1" -+ key_type="$2" - +- - # Seal the key into TPM - tpm2_create -Q \ - -C "${primary_file}" \ @@ tests/tpm2_key_protector_test.in: EOF - echo "Failed to flush the transient handles: ${ret}" >&2 - return 1 - fi -+ extra_opt="" -+ extra_grub_opt="" - +- - tpm2_load -Q \ - -C "${primary_file}" \ - -u "${keypub_file}" \ @@ tests/tpm2_key_protector_test.in: EOF - if [ "${ret}" -ne 0 ]; then - echo "Failed to flush the transient handles: ${ret}" >&2 - return 1 -+ if [ "$handle_type" == "nvindex" ]; then -+ nv_index="0x1000000" -+ else -+ nv_index="0x81000000" - fi - +- fi +- - tpm2_evictcontrol -Q -C o -c "${sealing_ctx_file}" ${nv_index} || ret=$? - if [ "${ret}" -ne 0 ]; then - echo "Failed to store the sealed key into ${nv_index}: ${ret}" >&2 - return 1 -+ if [ "$key_type" == "tpm2key" ]; then -+ extra_opt="--tpm2key" -+ else -+ extra_grub_opt="--pcrs=0,1" - fi - +- fi +- - return 0 -} - --tpm2_seal_unseal_nv() { -- nv_index="0x81000000" + tpm2_seal_unseal_nv() { + nv_index="0x81000000" - pcr_list="sha256:0,1" -- + grub_cfg=${tpm2testdir}/testcase.cfg # Seal the key into a NV index guarded by PCR 0 and 1 @@ tests/tpm2_key_protector_test.in: EOF return 99 fi - # Write the TPM unsealing script - cat > ${grub_cfg} <<EOF - loopback luks (host)${luksfile} --tpm2_key_protector_init --mode=nv --nvindex=${nv_index} --pcrs=0,1 -+tpm2_key_protector_init --mode=nv --nvindex=${nv_index} ${extra_grub_opt} - if cryptomount -a --protector tpm2; then - cat (crypto0)+1 - fi @@ tests/tpm2_key_protector_test.in: EOF ${grubshell} --timeout=${timeout} --emu-opts="-t ${tpm2dev}" < "${grub_cfg}" > "${testoutput}" || ret=$? @@ tests/tpm2_key_protector_test.in: EOF if [ "${ret}" -eq 0 ]; then if ! grep -q "^${vtext}$" "${testoutput}"; then -@@ tests/tpm2_key_protector_test.in: srktests+=("ECC transient fallback_srk") - for i in "${!srktests[@]}"; do - tpm2_seal_unseal ${srktests[$i]} || ret=$? - if [ "${ret}" -eq 0 ]; then -- echo "TPM2 [${srktests[$i]}]: PASS" -+ echo "TPM2 [SRK][${srktests[$i]}]: PASS" - elif [ "${ret}" -eq 1 ]; then -- echo "TPM2 [${srktests[$i]}]: FAIL" -+ echo "TPM2 [SRK][${srktests[$i]}]: FAIL" -+ ret=0 - else -- echo "Unexpected failure [${srktests[$i]}]" >&2 -+ echo "Unexpected failure [SRK][${srktests[$i]}]" >&2 - exit ${ret} - fi - done - --# Testcase for NV index mode --tpm2_seal_unseal_nv || ret=$? --if [ "${ret}" -eq 0 ]; then -- echo "TPM2 [NV Index]: PASS" --elif [ "${ret}" -eq 1 ]; then -- echo "TPM2 [NV Index]: FAIL" --else -- echo "Unexpected failure [NV index]" >&2 -- exit ${ret} --fi -+# Testcases for NV index mode -+declare -a nvtests=() -+nvtests+=("persistent raw") -+nvtests+=("nvindex raw") -+nvtests+=("nvindex tpm2key") -+ -+for i in "${!nvtests[@]}"; do -+ tpm2_seal_unseal_nv ${nvtests[$i]} || ret=$? -+ if [ "${ret}" -eq 0 ]; then -+ echo "TPM2 [NV Index][${nvtests[$i]}]: PASS" -+ elif [ "${ret}" -eq 1 ]; then -+ echo "TPM2 [NV Index][${nvtests[$i]}]: FAIL" -+ ret=0 -+ else -+ echo "Unexpected failure [NV index][${nvtests[$i]}]" >&2 -+ exit ${ret} -+ fi -+done - - exit 0 -: --------- > 9: b835df89e tests/tpm2_key_protector_test: Reset 'ret' on fail -: --------- > 10: 4c0cc50a5 tests/tpm2_key_protector_test: Add more NV index mode tests 10: b782d0bdb ! 11: 156c81422 docs: Update NV index mode of TPM2 key protector @@ docs/grub.texi: When/After the shim or GRUB are updated, it only requires to run +The range of persistent handles is from @kbd{0x81000000} to @kbd{0x81FFFFFF}. +The persistent handle is designed to make TPM objects persistent through +power cycles, and only TPM objects, such as RSA or EC keys, are accepted. -+Thus, TPM 2.0 Key File format is not supported by persistent handles. The -+following shows the @command{grub-protect} command to seal the disk key -+@file{luks.key} into the persistent handle @kbd{0x81000000} with the PCRs -+@kbd{0,2,4,7}. ++Thus, only the raw format is supported by persistent handles. The following ++shows the @command{grub-protect} command to seal the disk key @file{luks.key} ++into the persistent handle @kbd{0x81000000} with the PCRs @kbd{0,2,4,7}. @example -# @kbd{tpm2_createprimary -C o -g sha256 -G ecc -c primary.ctx} -: --------- > 12: f47758510 INSTALL: Document the packages needed for TPM2 key protector tests -- 2.43.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel