[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v14 00/20] Automatic Disk Unlock with TPM2
From: |
Gary Lin |
Subject: |
[PATCH v14 00/20] Automatic Disk Unlock with TPM2 |
Date: |
Fri, 3 May 2024 14:48:36 +0800 |
GIT repo for v14: https://github.com/lcp/grub2/tree/tpm2-unlock-v14
This patch series is based on "Automatic TPM Disk Unlock"(*1) posted by
Hernan Gatta to introduce the key protector framework and TPM2 stack
to GRUB2, and this could be a useful feature for the systems to
implement full disk encryption.
To support TPM 2.0 Key File format(*2), patch 1~5,7 are grabbed from
Daniel Axtens's "appended signature secure boot support" (*3) to import
libtasn1 into grub2. Besides, the libtasn1 version is upgraded to
4.19.0 instead of 4.16.0 in the original patch.
Patch 6 fixes a potential buffer overrun in libtasn1.
(https://gitlab.com/gnutls/libtasn1/-/issues/49)
Patch 8 adds the document for libtasn1 and the steps to upgrade the
library.
Patch 9~13 are Hernan Gatta's patches with the follow-up fixes and
improvements:
- Converting 8 spaces into 1 tab
- Merging the minor build fix from Michael Chang
- Replacing "lu" with "PRIuGRUB_SIZE" for grub_dprintf
- Adding "enable = efi" to the tpm2 module in grub-core/Makefile.core.def
- Rebasing "cryptodisk: Support key protectors" to the git master
- Removing the measurement on the sealed key
- Based on the patch from Olaf Kirch <OKir@suse.com>
- Adjusting the input parameters of TPM2_EvictControl to match the order
in "TCG TPM2 Part3 Commands"
- Declaring the input arguments of TPM2 functions as const
- Resending TPM2 commands on TPM_RC_RETRY
- Adding checks for the parameters of TPM2 commands
- Packing the missing authorization command for TPM2_PCR_Read
- Tweaking the TPM2 command functions to allow some parameters to be
NULL so that we don't have to declare empty variables
- Only enabling grub-protect for "efi" since the TPM2 stack currently
relies on the EFI TCG2 protocol to send TPM2 commands
- Using grub_cpu_to_be*() in the TPM2 stack instead of grub_swap_bytes*()
which may cause problems in big-indian machines
- Changing the short name of "--protector" of "cryptomount" from "-k" to
"-P" to avoid the conflict with "--key-file"
- Supporting TPM 2.0 Key File Format besides the raw sealed key
- Adding the external libtasn1 dependency to grub-protect to write the
TPM 2.0 Key files
- Extending the TPM2 TSS stack to support authorized policy
Patch 14 implements the authorized policy support.
Patch 15 implements the missing NV index mode. (Thanks to Patrick Colp)
Patch 16 improves the 'cryptomount' command to fall back to the
passphrase mode when the key protector fails to unlock the encrypted
partition. (Another patch from Patrick Colp)
Patch 17 and 18 fix the potential security issues spotted by Fabian Vogt.
Patch 19 and 20 implement the TPM key unsealing testcases.
To utilize the TPM2 key protector to unlock the encrypted partition
(sdb1), here are the sample steps:
1. Add an extra random key for LUKS (luks-key)
$ dd if=/dev/urandom of=luks-key bs=1 count=32
$ sudo cryptsetup luksAddKey /dev/sdb1 luks-key --pbkdf=pbkdf2
2. Seal the key
$ sudo grub-protect --action=add \
--protector=tpm2 \
--tpm2key \
--tpm2-keyfile=luks-key \
--tpm2-outfile=/boot/efi/boot/grub2/sealed.tpm
3. Unseal the key with the proper commands in grub.cfg:
tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
cryptomount -u <SDB1_UUID> -P tpm2
(*1) https://lists.gnu.org/archive/html/grub-devel/2022-02/msg00006.html
(*2) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
(*3) https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00044.html
v14:
- Addressing the libtasn1 patches more in the document
- Various improvements in tpm2_test
- Verifying the test inside the LUKS device
- Improving the return status checks and the waiting loop for swtpm
- Fixing the portability issues
- Making all variables braced
- Renaming grub-emu-opts to --emu-opts (grub-shell)
v13:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00155.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v13
- Fixing typos and a few multi-line comments
- Improving the conditional checks for the arguments of
tpm2_key_protector_init
- Updating to the latest TPM 2.0 Key File format
- Adding the new optional fields: description and rsaParent
- Handling "rsaParent == TRUE" when unsealing the tpm2key
- Setting "rsaParent" to "TRUE" when sealing the key with RSA SRK
- Removing non-standard SRKs: RSA3072, RSA4096, ECC_NIST_P384,
ECC_NIST_P521, and ECC_SM2_P256
- Adding more error messages to grub-protect
- Improving the error checking for the swtpm chardev instance
- Exiting the tpm2_test script if grub-protect failed to seal the key
v12:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00108.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v12
- Fixing typos and indentation
- Removing the unused TPM commands: TPM2_HashSequenceStart,
TPM2_SequenceUpdate, and TPM2_SequenceComplete,
- Following the TCG EK templates to set the parameters of SRK
- Removing ECC_BN_P256 and ECC_BN_P638 from the SRK algorithm list since
those two algorithms are not mentioned in the TCG EK templates
- Updating the help messages of the tpm2 module and grub-protect
- Removing the unnecessary NULL checks
- Adding the manpage for grub-protect
- Replacing grub_crypto_hash() with TPM2_Hash() in grub-protect to
support SHA384 PCR banks
- Using 'swtpm chardev' to start swtpm instead of 'swtpm_cuse' since
some distros may not build swtpm with cuse
- Adding a new testcase without specifying the SRK type to test the
default SRK settings
- Amending tpm2_test to remove the duplicate error checking code
- Silencing the tpm2-tools commands in tpm2_test
- Fixing the exit trap of tpm2_test to removing the working directory
on success
v11:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00052.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v11
- Adding the missing default: handlers in grub-core/tpm2/mu.c
- Updating the help messages and commit messages to reflect the change
of the default SRK algorithm (RSA2048 -> ECC_NIST_P256)
- Adding the testcase for the NV index mode
v10:
- https://lists.gnu.org/archive/html/grub-devel/2024-04/msg00019.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v10
- Fixing the coverity issues: CID 435775, CID 435771, CID 435770, CID
435769, CID 435767, CID 435761
https://lists.gnu.org/archive/html/grub-devel/2024-02/txtKIuUb5lf3O.txt
- Fixing the potential memory leak (CID 435775)
- Removing the unnecessary grub_protect_get_grub_drive_for_file() from
util/grub-protect.c (CID 435771)
- Using the grub_tpm2_mu_TPM2B_*_Unmarshal functions to unmarshal the
TPM2B structs instead of a generic grub_tpm2_mu_TPM2B_Unmarshal
(CID 435770)
- Fixing Null pointer dereference (CID 435769)
- Adding bound checks to grub_tpm2_mu_TPML_DIGEST_Unmarshal()
(CID 435767)
- Improving the check for the return value of ftell() (CID 435761)
- Adding a quick fix for CID 435762
- Removing the empty ending line in tests/asn1_test.in
- Fixing docs/grub-dev.texi and updating the libtasn1 patches in
grub-core/lib/libtasn1-patches/
- Merging all the TPM2 TSS stack patches into one to reduce the total
patch number
- Switching the default asymmetric algorithm from RSA2048 to
TPM_ECC_NIST_P256 for the faster key generation
- Adding the fallback SRK templates to try a few more SRK types in case
grub2 failed to associate the sealed key with the SRK in the persistent
handle or the default SRK
- Improving the test script to add tests for the persistent handle and
the fallback SRKs
v9:
- https://lists.gnu.org/archive/html/grub-devel/2024-02/msg00007.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v9
- Introducing c-ctype.h to posix_wrap and implementing strncat
- Adding the descriptive comments to the disabled code in libtasn1
- Replacing strcat with the bound-checked _asn1_str_cat in libtasn1 and
including c-ctype.h directly
- Integrating the asn1 testcases into "functional_test"
- Updating the libtasn1 patches mentioned in the documentation
- Moving the key protector to a module
- Amending configure.ac to enable/disable grub-protect
- Fixing an timeout issue in the tpm2_test script by feeding the config
through stdin
v8:
- https://lists.gnu.org/archive/html/grub-devel/2024-01/msg00013.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v8
- Introducing TPM device support to grub-emu and adding the TPM key
unsealing testcase
v7:
- https://lists.gnu.org/archive/html/grub-devel/2023-11/msg00127.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v7
- Stopping reading SRK from the well-known persistent handle (TPM2_SRK_HANDLE,
i.e. 0x81000001) by default since the persistent handle may be created
by other OS and causes unsealing failure due to SRK mismatching
- The user now has to specify the persistent handle with "--srk"
explicitly.
- Utilizing grub_error() to print more error messages
- Unifying the format of the error messages from TPM2 commands
v6:
- https://lists.gnu.org/archive/html/grub-devel/2023-10/msg00026.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v6
- Supporting more SRK types than RSA2048 and ECC_NIST_P256
- Documenting SHA512 as the supported PCR bank type in the tpm2
protector
- Removing the redundant error message for grub_tpm2_protector_srk_get()
since it may overwrite the real error message.
- Updating the supported SRK types and PCR bank types in grub-protect
- Removing the unused type: TPM2_ECC_CURVE
v5:
- https://lists.gnu.org/archive/html/grub-devel/2023-08/msg00113.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v5
- Rebasing to the latest git HEAD and improving the commit messages
- Implementing authorized poilcy support
- Implementing NV index mode
- Improving the 'cryptomount' command to fall back to the passphrase
mode when the key protector fails to unlock the encrypted partition
- Fixing the potential security issues
v4:
- https://lists.gnu.org/archive/html/grub-devel/2023-04/msg00104.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v4
- Improving the error condition checks in cryptodisk.c
- Moving the code to unseal with the standalone policy sequence below
the code for authpolicy sequence
- The standalone policy sequence was mistakenly prepended to to the
authpolicy sequence with grub_list_push() while it should be
appended.
- Pushing the error messages from the authpolicy sequence into the
grub_error stack so that we can list all errors from the sequence
- Improving the error messages in the TPM2 protector
- Amending the calculation of the max string lengths of 'Policy',
'CommandCode' and 'CommandPolicy'
- Skipping the error path in grub_tpm2key_get_authpolicy_seq() on
success to avoid freeing the authpolicy sequence
v3:
- https://lists.gnu.org/archive/html/grub-devel/2023-04/msg00055.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v3
- Adding the document for libtasn1
- Improving the error condition checks
ex: "if (!ptr)" ==> "if (ptr == NULL)"
"if (err)" ==> "if (err != GRUB_ERR_NONE)"
"if (rc)" ==> "if (rc != TPM_RC_SUCCESS)"
- Supporting the "TPMPolicy" and "TPMAuthPolicy" sequence in the TPM 2.0
key File
- Refactoring the key recover function to support "TPMPolicy" and
"TPMAuthPolicy" sequence
- Using TPMS_PCR_SELECTION_SelectPCR() to set the PCR bit mask
- Also dropping TPM2_PCR_TO_SELECT() and TPM2_PCR_TO_BIT() which are
not necessary anymore
- Removing the redundant variable, 'crd', from
grub_cryptodisk_scan_device_real()
- Fixing the spaces/tabs in cryptodisk.c
- Fixing the comment format in cryptodisk.h
- Adding the defensive check for "cargs->protectors" in
grub_cryptodisk_scan_device()
- Improving 'grub-protect' for the better support of TPM 2.0 Key File
- Adding more comments
v2:
- https://lists.gnu.org/archive/html/grub-devel/2023-03/msg00094.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock-v2
v1:
- https://lists.gnu.org/archive/html/grub-devel/2023-02/msg00130.html
- GIT repo: https://github.com/lcp/grub2/tree/tpm2-unlock
Daniel Axtens (6):
posix_wrap: tweaks in preparation for libtasn1
libtasn1: import libtasn1-4.19.0
libtasn1: disable code not needed in grub
libtasn1: changes for grub compatibility
libtasn1: compile into asn1 module
asn1_test: test module for libtasn1
Gary Lin (7):
libtasn1: fix the potential buffer overrun
libtasn1: Add the documentation
tpm2: Support authorized policy
cryptodisk: wipe out the cached keys from protectors
diskfilter: look up cryptodisk devices first
tpm2: Enable tpm2 module for grub-emu
tests: Add tpm2_test
Hernan Gatta (5):
key_protector: Add key protectors framework
tpm2: Add TPM Software Stack (TSS)
key_protector: Add TPM2 Key Protector
cryptodisk: Support key protectors
util/grub-protect: Add new tool
Patrick Colp (2):
tpm2: Implement NV index
cryptodisk: Fallback to passphrase
.gitignore | 2 +
Makefile.util.def | 37 +
configure.ac | 30 +
docs/grub-dev.texi | 34 +
docs/man/grub-protect.h2m | 4 +
grub-core/Makefile.am | 1 +
grub-core/Makefile.core.def | 48 +
grub-core/disk/cryptodisk.c | 183 +-
grub-core/disk/diskfilter.c | 35 +-
grub-core/disk/key_protector.c | 78 +
grub-core/kern/emu/main.c | 11 +-
grub-core/kern/emu/misc.c | 51 +
...asn1-disable-code-not-needed-in-grub.patch | 320 +++
...tasn1-changes-for-grub-compatibility.patch | 135 +
...sn1-fix-the-potential-buffer-overrun.patch | 35 +
grub-core/lib/libtasn1/COPYING | 16 +
grub-core/lib/libtasn1/README.md | 98 +
grub-core/lib/libtasn1/lib/coding.c | 1433 ++++++++++
grub-core/lib/libtasn1/lib/decoding.c | 2503 +++++++++++++++++
grub-core/lib/libtasn1/lib/element.c | 1109 ++++++++
grub-core/lib/libtasn1/lib/element.h | 42 +
grub-core/lib/libtasn1/lib/errors.c | 103 +
grub-core/lib/libtasn1/lib/gstr.c | 74 +
grub-core/lib/libtasn1/lib/gstr.h | 50 +
grub-core/lib/libtasn1/lib/int.h | 220 ++
grub-core/lib/libtasn1/lib/parser_aux.c | 1178 ++++++++
grub-core/lib/libtasn1/lib/parser_aux.h | 172 ++
grub-core/lib/libtasn1/lib/structure.c | 1227 ++++++++
grub-core/lib/libtasn1/lib/structure.h | 46 +
grub-core/lib/libtasn1_wrap/wrap.c | 26 +
grub-core/lib/posix_wrap/c-ctype.h | 114 +
grub-core/lib/posix_wrap/limits.h | 1 +
grub-core/lib/posix_wrap/stdlib.h | 8 +
grub-core/lib/posix_wrap/string.h | 21 +
grub-core/lib/posix_wrap/sys/types.h | 1 +
.../tests/asn1/CVE-2018-1000654-1_asn1_tab.h | 32 +
.../tests/asn1/CVE-2018-1000654-2_asn1_tab.h | 36 +
grub-core/tests/asn1/CVE-2018-1000654.c | 58 +
grub-core/tests/asn1/Test_overflow.c | 134 +
grub-core/tests/asn1/Test_simple.c | 205 ++
grub-core/tests/asn1/Test_strings.c | 142 +
grub-core/tests/asn1/asn1_test.c | 49 +
grub-core/tests/asn1/asn1_test.h | 44 +
grub-core/tests/asn1/object-id-decoding.c | 109 +
grub-core/tests/asn1/object-id-encoding.c | 114 +
grub-core/tests/asn1/octet-string.c | 199 ++
grub-core/tests/asn1/reproducers.c | 80 +
grub-core/tests/lib/functional_test.c | 1 +
grub-core/tpm2/args.c | 140 +
grub-core/tpm2/buffer.c | 145 +
grub-core/tpm2/module.c | 1325 +++++++++
grub-core/tpm2/mu.c | 1168 ++++++++
grub-core/tpm2/tcg2-emu.c | 52 +
grub-core/tpm2/tcg2.c | 143 +
grub-core/tpm2/tpm2.c | 1048 +++++++
grub-core/tpm2/tpm2key.asn | 33 +
grub-core/tpm2/tpm2key.c | 476 ++++
grub-core/tpm2/tpm2key_asn1_tab.c | 45 +
include/grub/cryptodisk.h | 16 +
include/grub/emu/misc.h | 5 +
include/grub/key_protector.h | 46 +
include/grub/libtasn1.h | 657 +++++
include/grub/tpm2/buffer.h | 65 +
include/grub/tpm2/internal/args.h | 49 +
include/grub/tpm2/internal/functions.h | 156 +
include/grub/tpm2/internal/structs.h | 768 +++++
include/grub/tpm2/internal/types.h | 403 +++
include/grub/tpm2/mu.h | 396 +++
include/grub/tpm2/tcg2.h | 34 +
include/grub/tpm2/tpm2.h | 34 +
include/grub/tpm2/tpm2key.h | 86 +
tests/asn1_test.in | 11 +
tests/tpm2_test.in | 306 ++
tests/util/grub-shell.in | 6 +-
util/grub-protect.c | 1420 ++++++++++
75 files changed, 19639 insertions(+), 43 deletions(-)
create mode 100644 docs/man/grub-protect.h2m
create mode 100644 grub-core/disk/key_protector.c
create mode 100644
grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch
create mode 100644
grub-core/lib/libtasn1-patches/0002-libtasn1-changes-for-grub-compatibility.patch
create mode 100644
grub-core/lib/libtasn1-patches/0003-libtasn1-fix-the-potential-buffer-overrun.patch
create mode 100644 grub-core/lib/libtasn1/COPYING
create mode 100644 grub-core/lib/libtasn1/README.md
create mode 100644 grub-core/lib/libtasn1/lib/coding.c
create mode 100644 grub-core/lib/libtasn1/lib/decoding.c
create mode 100644 grub-core/lib/libtasn1/lib/element.c
create mode 100644 grub-core/lib/libtasn1/lib/element.h
create mode 100644 grub-core/lib/libtasn1/lib/errors.c
create mode 100644 grub-core/lib/libtasn1/lib/gstr.c
create mode 100644 grub-core/lib/libtasn1/lib/gstr.h
create mode 100644 grub-core/lib/libtasn1/lib/int.h
create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c
create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.h
create mode 100644 grub-core/lib/libtasn1/lib/structure.c
create mode 100644 grub-core/lib/libtasn1/lib/structure.h
create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c
create mode 100644 grub-core/lib/posix_wrap/c-ctype.h
create mode 100644 grub-core/tests/asn1/CVE-2018-1000654-1_asn1_tab.h
create mode 100644 grub-core/tests/asn1/CVE-2018-1000654-2_asn1_tab.h
create mode 100644 grub-core/tests/asn1/CVE-2018-1000654.c
create mode 100644 grub-core/tests/asn1/Test_overflow.c
create mode 100644 grub-core/tests/asn1/Test_simple.c
create mode 100644 grub-core/tests/asn1/Test_strings.c
create mode 100644 grub-core/tests/asn1/asn1_test.c
create mode 100644 grub-core/tests/asn1/asn1_test.h
create mode 100644 grub-core/tests/asn1/object-id-decoding.c
create mode 100644 grub-core/tests/asn1/object-id-encoding.c
create mode 100644 grub-core/tests/asn1/octet-string.c
create mode 100644 grub-core/tests/asn1/reproducers.c
create mode 100644 grub-core/tpm2/args.c
create mode 100644 grub-core/tpm2/buffer.c
create mode 100644 grub-core/tpm2/module.c
create mode 100644 grub-core/tpm2/mu.c
create mode 100644 grub-core/tpm2/tcg2-emu.c
create mode 100644 grub-core/tpm2/tcg2.c
create mode 100644 grub-core/tpm2/tpm2.c
create mode 100644 grub-core/tpm2/tpm2key.asn
create mode 100644 grub-core/tpm2/tpm2key.c
create mode 100644 grub-core/tpm2/tpm2key_asn1_tab.c
create mode 100644 include/grub/key_protector.h
create mode 100644 include/grub/libtasn1.h
create mode 100644 include/grub/tpm2/buffer.h
create mode 100644 include/grub/tpm2/internal/args.h
create mode 100644 include/grub/tpm2/internal/functions.h
create mode 100644 include/grub/tpm2/internal/structs.h
create mode 100644 include/grub/tpm2/internal/types.h
create mode 100644 include/grub/tpm2/mu.h
create mode 100644 include/grub/tpm2/tcg2.h
create mode 100644 include/grub/tpm2/tpm2.h
create mode 100644 include/grub/tpm2/tpm2key.h
create mode 100644 tests/asn1_test.in
create mode 100644 tests/tpm2_test.in
create mode 100644 util/grub-protect.c
Range-diff against v13:
-: --------- > 1: c6a7b2a55 posix_wrap: tweaks in preparation for libtasn1
-: --------- > 2: c2dfb28d9 libtasn1: import libtasn1-4.19.0
-: --------- > 3: f5c15acce libtasn1: disable code not needed in grub
1: 60cf41fa3 ! 4: 30271d827 libtasn1: changes for grub compatibility
@@ Commit message
Cc: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Gary Lin <glin@suse.com>
+ Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
## grub-core/lib/libtasn1/lib/decoding.c ##
@@ grub-core/lib/libtasn1/lib/decoding.c: asn1_expand_octet_string
(asn1_node_const definitions, asn1_node * element,
2: ce32406ca = 5: 9eb5bb4fc libtasn1: fix the potential buffer overrun
3: 6410e21d8 = 6: ef1e5cfe7 libtasn1: compile into asn1 module
4: a94e1b32c = 7: f851596f8 asn1_test: test module for libtasn1
5: 0e6041be0 ! 8: f04612ab5 libtasn1: Add the documentation
@@ docs/grub-dev.texi: cp minilzo-2.10/*.[hc] grub-core/lib/minilzo
+rm -rf libtasn1-4.19.0
+@end example
+
-+After upgrading the library, it is necessary to apply the patches in
++After upgrading the library, it may be necessary to apply the patches in
+@file{grub-core/lib/libtasn1-patches/} to adjust the code to be
compatible with
-+grub.
++grub. These patches were needed to use the current version of libtasn1.
The
++existing patches may not apply cleanly, apply at all, or even be needed
for a
++newer version of the library, and other patches maybe needed due to
changes in
++the newer version. If existing patches need to be refreshed to apply
cleanly,
++please include updated patches as part of the a patch set sent to the
list.
++If new patches are needed or existing patches are not needed, also please
send
++additions or removals as part of any patch set upgrading libtasn1.
+
@node Debugging
@chapter Debugging
6: 386e4c04b = 9: e03991256 key_protector: Add key protectors framework
7: 13117460e = 10: f3368e733 tpm2: Add TPM Software Stack (TSS)
8: 758d6ec5f = 11: 86495e70d key_protector: Add TPM2 Key Protector
9: e3354505d = 12: 3e5484cf0 cryptodisk: Support key protectors
10: 9d5da3317 = 13: b7bd289b6 util/grub-protect: Add new tool
11: 3207f30a9 = 14: 7cb1d9740 tpm2: Support authorized policy
12: 5f22e6397 = 15: d7b4b99a9 tpm2: Implement NV index
13: 64c386176 = 16: d48b1ac29 cryptodisk: Fallback to passphrase
14: c65391cc2 = 17: 0cfc6d2b7 cryptodisk: wipe out the cached keys from
protectors
15: d285e9dc1 = 18: 8c7507f0f diskfilter: look up cryptodisk devices first
16: 669b56fb3 = 19: 64f1a3e02 tpm2: Enable tpm2 module for grub-emu
17: 0a2d6d64c ! 20: 665ce495d tests: Add tpm2_test
@@ Commit message
Cc: Michael Chang <mchang@suse.com>
Cc: Stefan Berger <stefanb@linux.ibm.com>
+ Cc: Glenn Washburn <development@efficientek.com>
Signed-off-by: Gary Lin <glin@suse.com>
## Makefile.util.def ##
@@ tests/tpm2_test.in (new)
+
+. "@builddir@/grub-core/modinfo.sh"
+
-+if [ x$grub_modinfo_platform != xemu ]; then
++if [ x${grub_modinfo_platform} != xemu ]; then
+ exit 77
+fi
+
+builddir="@builddir@"
+
+# Force build directory components
-+PATH="${builddir}:$PATH"
++PATH="${builddir}:${PATH}"
+export PATH
+
-+if [ "x$EUID" = "x" ] ; then
++if [ "x${EUID}" = "x" ] ; then
+ EUID=`id -u`
+fi
+
-+if [ "$EUID" != 0 ] ; then
++if [ "${EUID}" != 0 ] ; then
+ echo "not root; cannot test tpm2."
+ exit 99
+fi
+
-+if ! which cryptsetup >/dev/null 2>&1; then
++if ! command -v cryptsetup >/dev/null 2>&1; then
+ echo "cryptsetup not installed; cannot test tpm2."
+ exit 99
+fi
@@ tests/tpm2_test.in (new)
+ exit 99
+fi
+
-+if ! which swtpm >/dev/null 2>&1; then
++if ! command -v swtpm >/dev/null 2>&1; then
+ echo "swtpm not installed; cannot test tpm2."
+ exit 99
+fi
+
-+if ! which tpm2_startup >/dev/null 2>&1; then
++if ! command -v tpm2_startup >/dev/null 2>&1; then
+ echo "tpm2-tools not installed; cannot test tpm2."
+ exit 99
+fi
+
-+tpm2testdir="`mktemp -d "${TMPDIR:-/tmp}/$(basename "$0").XXXXXXXXXX"`"
|| exit 20
++tpm2testdir="`mktemp -d "${TMPDIR:-/tmp}/$(basename "$0").XXXXXXXXXX"`"
|| exit 99
+
+disksize=20M
+
-+luksfile=$tpm2testdir/luks.disk
++luksfile=${tpm2testdir}/luks.disk
+lukskeyfile=${tpm2testdir}/password.txt
+
+# Choose a low iteration number to reduce the time to decrypt the disk
@@ tests/tpm2_test.in (new)
+
+timeout=20
+
-+testoutput=$tpm2testdir/testoutput
++testoutput=${tpm2testdir}/testoutput
+
+vtext="TEST VERIFIED"
+
++ret=0
++
+# Create the password file
+echo -n "top secret" > ${lukskeyfile}
+
@@ tests/tpm2_test.in (new)
+truncate -s ${disksize} ${luksfile} || exit 21
+cryptsetup luksFormat -q ${csopt} ${luksfile} ${lukskeyfile} || exit 22
+
++# Write vtext into the first block of the LUKS2 image
++luksdev=/dev/mapper/`basename ${tpm2testdir}`
++cryptsetup open --key-file ${lukskeyfile} ${luksfile} `basename
${luksdev}` || exit 23
++echo "${vtext}" | dd of=${luksdev} conv=notrunc status=none
++cryptsetup close ${luksdev}
++
+# Shutdown the swtpm instance on exit
+cleanup() {
+ RET=$?
-+ if [ -e "$tpm2ctrl" ]; then
-+ swtpm_ioctl -s --unix ${tpm2ctrl}
++ if [ -e "${tpm2ctrl}" ]; then
++ swtpm_ioctl -s --unix ${tpm2ctrl}
+ fi
+ if [ "${RET}" -eq 0 ]; then
-+ rm -rf "$tpm2testdir" || :
++ rm -rf "$tpm2testdir" || :
+ fi
+}
+trap cleanup EXIT INT TERM KILL QUIT
@@ tests/tpm2_test.in (new)
+# Create the swtpm chardev instance
+swtpm chardev --vtpm-proxy --tpmstate dir=${tpm2statedir} \
+ --tpm2 --ctrl type=unixio,path=${tpm2ctrl} \
-+ --flags startup-clear --daemon > ${tpm2log}
-+ret=$?
-+if [ "$ret" -ne 0 ]; then
-+ exit $ret
++ --flags startup-clear --daemon > ${tpm2log} || ret=$?
++if [ "${ret}" -ne 0 ]; then
++ echo "Failed to start swtpm chardev"
++ exit ${ret}
+fi
+
+# Wait for tpm2 chardev
-+wait=3
-+while [ "${wait}" -gt 0 ]; do
++wait_count=3
++for count in `seq 1 ${wait_count}`; do
++ sleep 1
++
+ tpm2dev=$(grep "New TPM device" ${tpm2log} | cut -d' ' -f 4)
-+ if [ -n "${tpm2dev}" ] && [ -c "${tpm2dev}" ]; then
-+ break
++ if [ -c "${tpm2dev}" ]; then
++ wait_count=0
++ break
+ fi
-+ sleep 1
-+ ((wait--))
+done
-+if [ "$wait" -le 0 ]; then
++if [ "${wait_count}" -ne 0 ]; then
+ echo "TPM device did not appear."
+ exit QUIT
+fi
@@ tests/tpm2_test.in (new)
+export TPM2TOOLS_TCTI="device:${tpm2dev}"
+
+# Extend PCR 0
-+tpm2_pcrextend 0:sha256=$(sha256sum <<< "test0" | cut -d ' ' -f 1)
-+ret=$?
-+if [ "$ret" -ne 0 ]; then
-+ exit $ret
-+fi
++tpm2_pcrextend 0:sha256=$(echo "test0" | sha256sum | cut -d ' ' -f 1)
+
+# Extend PCR 1
-+tpm2_pcrextend 1:sha256=$(sha256sum <<< "test1" | cut -d ' ' -f 1)
-+ret=$?
-+if [ "$ret" -ne 0 ]; then
-+ exit $ret
-+fi
++tpm2_pcrextend 1:sha256=$(echo "test1" | sha256sum | cut -d ' ' -f 1)
+
+tpm2_seal_unseal() {
-+ local srk_alg="$1"
-+ local handle_type="$2"
-+ local srk_test="$3"
++ srk_alg="$1"
++ handle_type="$2"
++ srk_test="$3"
+
-+ local grub_srk_alg=${srk_alg}
++ grub_srk_alg=${srk_alg}
+
-+ local extra_opt=""
-+ local extra_grub_opt=""
++ extra_opt=""
++ extra_grub_opt=""
+
-+ local persistent_handle="0x81000000"
++ persistent_handle="0x81000000"
+
-+ if [ "${handle_type}" == "persistent" ]; then
++ if [ "${handle_type}" = "persistent" ]; then
+ extra_opt="--tpm2-srk=${persistent_handle}"
+ fi
+
@@ tests/tpm2_test.in (new)
+
+ # Seal the password with grub-protect
+ grub-protect ${extra_opt} \
-+ --tpm2-device=${tpm2dev} \
-+ --action=add \
-+ --protector=tpm2 \
-+ --tpm2key \
-+ --tpm2-bank=sha256 \
-+ --tpm2-pcrs=0,1 \
-+ --tpm2-keyfile=${lukskeyfile} \
-+ --tpm2-outfile=${sealedkey}
-+ ret=$?
-+ if [ "$ret" -ne 0 ]; then
++ --tpm2-device=${tpm2dev} \
++ --action=add \
++ --protector=tpm2 \
++ --tpm2key \
++ --tpm2-bank=sha256 \
++ --tpm2-pcrs=0,1 \
++ --tpm2-keyfile=${lukskeyfile} \
++ --tpm2-outfile=${sealedkey} || ret=$?
++ if [ "${ret}" -ne 0 ]; then
+ echo "Failed to seal the secret key"
+ exit 1
+ fi
+
+ # Flip the asymmetric algorithm in grub.cfg to trigger fallback SRKs
-+ if [ "${srk_test}" == "fallback_srk" ]; then
-+ if [[ "${srk_alg}" == RSA* ]]; then
-+ grub_srk_alg="ECC"
-+ elif [[ "${srk_alg}" == ECC* ]]; then
-+ grub_srk_alg="RSA"
-+ fi
++ if [ "${srk_test}" = "fallback_srk" ]; then
++ if [ -z "${srk_alg##RSA*}" ]; then
++ grub_srk_alg="ECC"
++ elif [ -z "${srk_alg##ECC*}" ]; then
++ grub_srk_alg="RSA"
++ fi
+ fi
+
+ if [ "${grub_srk_alg}" != "default" ] && [ "${handle_type}" !=
"persistent" ]; then
@@ tests/tpm2_test.in (new)
+loopback luks (host)${luksfile}
+tpm2_key_protector_init -T (host)${sealedkey} ${extra_grub_opt}
+if cryptomount -a --protector tpm2; then
-+ echo "${vtext}"
++ cat (crypto0)+1
+fi
+EOF
+
+ # Test TPM unsealing with the same PCR
-+ ${grubshell} --timeout=$timeout --grub-emu-opts="-t ${tpm2dev}" <
${tpm2testdir}/testcase.cfg > ${testoutput}
-+ ret=$?
++ ${grubshell} --timeout=${timeout} --emu-opts="-t ${tpm2dev}" <
${tpm2testdir}/testcase.cfg > ${testoutput} || ret=$?
+
+ # Remove the persistent handle
-+ if [ "${handle_type}" == "persistent" ]; then
++ if [ "${handle_type}" = "persistent" ]; then
+ grub-protect \
+ --tpm2-device=${tpm2dev} \
+ --protector=tpm2 \
@@ tests/tpm2_test.in (new)
+ --tpm2-evict
+ fi
+
-+ if [ "$ret" -eq 0 ]; then
-+ if ! grep -q "^${vtext}$" "$testoutput"; then
-+ echo "error: test not verified [`cat $testoutput`]" >&2
++ if [ "${ret}" -eq 0 ]; then
++ if ! grep -q "^${vtext}$" "${testoutput}"; then
++ echo "error: test not verified [`cat ${testoutput}`]" >&2
+ exit 1
+ fi
+ else
-+ echo "grub-emu exited with error: $ret" >&2
-+ exit $ret
++ echo "grub-emu exited with error: ${ret}" >&2
++ exit ${ret}
+ fi
+}
+
+tpm2_seal_unseal_nv() {
-+ local persistent_handle="0x81000000"
-+ local primary_file=${tpm2testdir}/primary.ctx
-+ local session_file=${tpm2testdir}/session.dat
-+ local policy_file=${tpm2testdir}/policy.dat
-+ local keypub_file=${tpm2testdir}/key.pub
-+ local keypriv_file=${tpm2testdir}/key.priv
-+ local name_file=${tpm2testdir}/sealing.name
-+ local sealing_ctx_file=${tpm2testdir}/sealing.ctx
++ persistent_handle="0x81000000"
++ primary_file=${tpm2testdir}/primary.ctx
++ session_file=${tpm2testdir}/session.dat
++ policy_file=${tpm2testdir}/policy.dat
++ keypub_file=${tpm2testdir}/key.pub
++ keypriv_file=${tpm2testdir}/key.priv
++ name_file=${tpm2testdir}/sealing.name
++ sealing_ctx_file=${tpm2testdir}/sealing.ctx
+
+ # Since we don't run a resource manager on our swtpm instance, it has
+ # to flush the transient handles after tpm2_createprimary, tpm2_create
@@ tests/tpm2_test.in (new)
+loopback luks (host)${luksfile}
+tpm2_key_protector_init --mode=nv --nvindex=${persistent_handle}
--pcrs=0,1
+if cryptomount -a --protector tpm2; then
-+ echo "${vtext}"
++ cat (crypto0)+1
+fi
+EOF
+
+ # Test TPM unsealing with the same PCR
-+ ${grubshell} --timeout=$timeout --grub-emu-opts="-t ${tpm2dev}" <
${tpm2testdir}/testcase.cfg > ${testoutput}
-+ ret=$?
++ ${grubshell} --timeout=${timeout} --emu-opts="-t ${tpm2dev}" <
${tpm2testdir}/testcase.cfg > ${testoutput} || ret=$?
+
+ # Remove the persistent handle
+ grub-protect \
@@ tests/tpm2_test.in (new)
+ --tpm2-srk=${persistent_handle} \
+ --tpm2-evict
+
-+ if [ "$ret" -eq 0 ]; then
-+ if ! grep -q "^${vtext}$" "$testoutput"; then
-+ echo "error: test not verified [`cat $testoutput`]" >&2
++ if [ "${ret}" -eq 0 ]; then
++ if ! grep -q "^${vtext}$" "${testoutput}"; then
++ echo "error: test not verified [`cat ${testoutput}`]" >&2
+ exit 1
+ fi
+ else
-+ echo "grub-emu exited with error: $ret" >&2
-+ exit $ret
++ echo "grub-emu exited with error: ${ret}" >&2
++ exit ${ret}
+ fi
+}
+
@@ tests/util/grub-shell.in: work_directory=${WORKDIR:-`mktemp -d
"${TMPDIR:-/tmp}/
. "${builddir}/grub-core/modinfo.sh"
qemuopts=
-+grubemuopts=
++emuopts=
serial_port=com0
serial_null=
halt_cmd=halt
@@ tests/util/grub-shell.in: for option in "$@"; do
--qemu-opts=*)
qs=`echo "$option" | sed -e 's/--qemu-opts=//'`
qemuopts="$qemuopts $qs" ;;
-+ --grub-emu-opts=*)
-+ qs=`echo "$option" | sed -e 's/--grub-emu-opts=//'`
-+ grubemuopts="$grubemuopts $qs" ;;
++ --emu-opts=*)
++ qs=`echo "$option" | sed -e 's/--emu-opts=//'`
++ emuopts="$emuopts $qs" ;;
--disk=*)
dsk=`echo "$option" | sed -e 's/--disk=//'`
if [ ${grub_modinfo_platform} = emu ]; then
@@ tests/util/grub-shell.in: elif [ x$boot = xemu ]; then
#! @BUILD_SHEBANG@
SDIR=\$(realpath -e \${0%/*})
-exec "$(realpath -e "${builddir}")/grub-core/grub-emu" -m
"\$SDIR/${device_map##*/}" --memdisk "\$SDIR/${roottar##*/}" -r memdisk -d
"/boot/grub"
-+exec "$(realpath -e "${builddir}")/grub-core/grub-emu" -m
"\$SDIR/${device_map##*/}" --memdisk "\$SDIR/${roottar##*/}" -r memdisk -d
"/boot/grub" ${grubemuopts}
++exec "$(realpath -e "${builddir}")/grub-core/grub-emu" -m
"\$SDIR/${device_map##*/}" --memdisk "\$SDIR/${roottar##*/}" -r memdisk -d
"/boot/grub" ${emuopts}
EOF
else
cat >"$work_directory/run.sh" <<EOF
--
2.35.3
- [PATCH v14 00/20] Automatic Disk Unlock with TPM2,
Gary Lin <=
- [PATCH v14 01/20] posix_wrap: tweaks in preparation for libtasn1, Gary Lin, 2024/05/03
- [PATCH v14 02/20] libtasn1: import libtasn1-4.19.0, Gary Lin, 2024/05/03
- [PATCH v14 05/20] libtasn1: fix the potential buffer overrun, Gary Lin, 2024/05/03
- [PATCH v14 03/20] libtasn1: disable code not needed in grub, Gary Lin, 2024/05/03
- [PATCH v14 07/20] asn1_test: test module for libtasn1, Gary Lin, 2024/05/03
- [PATCH v14 04/20] libtasn1: changes for grub compatibility, Gary Lin, 2024/05/03
- [PATCH v14 06/20] libtasn1: compile into asn1 module, Gary Lin, 2024/05/03
- [PATCH v14 17/20] cryptodisk: wipe out the cached keys from protectors, Gary Lin, 2024/05/03
- [PATCH v14 08/20] libtasn1: Add the documentation, Gary Lin, 2024/05/03
- [PATCH v14 11/20] key_protector: Add TPM2 Key Protector, Gary Lin, 2024/05/03