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

Reply via email to