Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autounlock ZFS Encrypted Root Filesystems using TPM 2.0 #9852

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ghfields
Copy link
Contributor

@ghfields ghfields commented Jan 16, 2020

Motivation and Context

Presently, native encryption of a ZFS root filesystem requires a passphrase or keyfile to be available every boot. A TPM 2.0 chip has the ability to store and release data, if certain criteria are met. This PR provides an optional method, which allows TPM 2.0 to be used to automatically unlock the filesystem, without user intervention.

This is a DRAFT PR to foster discussion surrounding the method. THIS MAY NOT CONFORM TO STYLE GUIDES OR EVEN GOOD CODING PRACTICES. Code nit comments are not unwelcome, but methodology is the initial goal.

Description

This PR does the following:

  • Within zfs's initramfs hooks, detects and copies needed tpm2-tools 4.x+ to the initrd
  • Provides zfs initramfs's script a method of detecting and unlocking using TPM2 tools
  • If TPM2 unlock is not successful, allows Initramfs to fallback to other manual passphrase methods
  • Stores required (and user definable) unlocking variables in the encryption root using org.openzfs.tpm2:index and org.openzfs.tpm2:pcrs
  • Provides a utility that maintains the TPM and the above zfs properties
  • The zfs passphrase is locked within the TPM's nvram, and only releasable with an expected PCR state and password (GUID used to confirm encrypted filesystem match)
  • The nvram region of the TPM is locked from further reading following the retrieval of the password within the initramfs script, preventing even root users access to the password post-boot.

Quick (and probably correctish) PCR usage:

PCR - Use
0 - Bios/Platform Code
1 - Bios/Platform Config
2 - Option Rom / UEFI Driver Code
3 - Option Rom / UEFI Config Data
4 - Bootloader code (GPT), boot attempts?
5 - Bootloader data
6 - Manufacturer use / wake events?
7 - Manufacturer use / Secureboot policy

8 - Grub 2.04 - Grub, Kernel, and Module Commands
9 - Grub 2.04 - ANY file read by Grub (includes kernel and initrd)
10 - Linux Integrity Measurement Architecture (IMA)

1-7 Hardware
8+ Operating System

How Has This Been Tested?

Tpm-tools 4.x revamped its arguments. Grub 2.04 is secure boot compatible and now reports additional boot time measurements that could harden the boot protections. Therefore, this has been developed and tested solely on Ubuntu Focal pre-release (to be 20.04 LTS) on Dell TPM 2.0 hardware using UEFI boot. Testing different distros, kernels, and hardware TPM devices need to be conducted.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (a change to man pages or other documentation)

Checklist:

  • My code follows the ZFS on Linux code style requirements.
  • I have updated the documentation accordingly.
  • I have read the contributing document.
  • I have added tests to cover my changes.
  • I have run the ZFS Test Suite with this change applied.
  • All commit messages are properly formatted and contain Signed-off-by.

Things to Explore / Current Status (will be edited over time)

  • Dracut integration
  • Include kernel commandline panic=5 monitoring/injection to prevent snooping from the initrd prompt
  • Consider updating TPM within the initrd, following autounlock failure, but successful manual entry (ie. after kernel/initrd updates)
  • Documentation of TPM PCRs
  • Consider the ability to use keyfiles (recovery method must match what is in the TPM)
  • Prove functionality on other platforms

Resources

Tpm2-tools man pages
Grub manual (specifically Measured Boot Section)
UEFI PCR explanation on Pg. 2
Another PCR description on 4th page

@behlendorf behlendorf added the Status: Design Review Needed Architecture or design is under discussion label Jan 16, 2020
@codecov
Copy link

codecov bot commented Jan 17, 2020

Codecov Report

Merging #9852 into master will decrease coverage by 0.42%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #9852      +/-   ##
==========================================
- Coverage   79.81%   79.39%   -0.43%     
==========================================
  Files         395      385      -10     
  Lines      125087   121481    -3606     
==========================================
- Hits        99836    96444    -3392     
+ Misses      25251    25037     -214     
Flag Coverage Δ
#kernel 79.66% <ø> (-0.73%) ⬇️
#user 66.77% <ø> (+0.82%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
module/os/linux/spl/spl-vmem.c 54.16% <0.00%> (-45.84%) ⬇️
lib/libzpool/util.c 76.04% <0.00%> (-20.17%) ⬇️
module/os/linux/spl/spl-kmem-cache.c 75.31% <0.00%> (-14.78%) ⬇️
include/os/linux/zfs/sys/trace_arc.h 85.71% <0.00%> (-14.29%) ⬇️
module/zfs/zrlock.c 86.15% <0.00%> (-10.57%) ⬇️
module/zfs/zfs_onexit.c 76.19% <0.00%> (-9.86%) ⬇️
module/zfs/aggsum.c 93.02% <0.00%> (-6.98%) ⬇️
lib/libtpool/thread_pool.c 53.00% <0.00%> (-5.68%) ⬇️
module/os/linux/spl/spl-err.c 30.55% <0.00%> (-5.56%) ⬇️
lib/libzfs/os/linux/libzfs_mount_os.c 63.71% <0.00%> (-5.16%) ⬇️
... and 254 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 417e646...d72c06d. Read the comment docs.

# Default variables
# If password is stored in "defaultpassword" field, ensure the security of the file.
defaultpassword=""
defaulttpmindex="0x1500016"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to:
https://trustedcomputinggroup.org/wp-content/uploads/RegistryOfReservedTPM2HandlesAndLocalities_v1p1_pub.pdf

The handle 0x1500016 is unassigned by TCG but reserved for the Platform manufacturer. You should probably pick something in the unassigned by TCG for Owner range of:
Start: 0x0180000016
End: 0x01BFFFFF16

1800000
1BFFFFF

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Will stay away from that range.

tpm2_nvundefine "$tpmindex" >/dev/null 2>&1

# Define NVRAM location and its access rules
cmd="tpm2_nvdefine ${tpmindex} -Q --hierarchy=o --index-auth=${rootguid} --size=512 --policy=policy.dat --attributes='policyread|policywrite|read_stclear'"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you setting --index-auth without attribute TPMA_NV_AUTHREAD? IIUC, that essentially is saying, hey this is another password but i never want to use it. I would imagine the rootguid is not a secret, and thus you really just want to drop this option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, seems redundant. "policyread and policywrite" are the only allowed access methods. The password requirement is built within the policy and is not freestanding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well..local testing didn't like removing --index-auth=${rootguid}. It resulted in:

WARNING:esys:src/tss2-esys/api/Esys_NV_Write.c:306:Esys_NV_Write_Finish() Received TPM Error 
ERROR:esys:src/tss2-esys/api/Esys_NV_Write.c:110:Esys_NV_Write() Esys Finish ErrorCode (0x0000098e) 
ERROR: Failed to write NV area at index 0x1500016
ERROR: Tss2_Sys_NV_Write(0x98E) - tpm:session(1):the authorization HMAC check failed and DA counter incremented
ERROR: Unable to run tpm2_nvwrite

When running tpm2_autounlock -p password. Looks like it stays.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably because you still have policypassword present, which doesn't make a whole lot sense with a known value. For something like an FS encryption key, you would probably want to tie it to:

  1. PCR state
  2. User supplied secret (optional yet encouraged, depends on what your doing)
  3. Recovery from owner hierarchy auth if user forgets passphrase or PCR state changes

Typically folks avoid hard-coding PCR's due to brittleness and use policyauthorize which says, use any policy signed by key X. Not sure what prevents rollback to a bad policy or OS state on that method, may be worth investigating. There might not be a mechanism there.. so maybe owner auth and re-creating the nv index will work for upgrade path.

The question is, for automount, where can we get the user password. Not sure where you can source it, from PAM, login session, kernel keyring, etc. I really don't know much about that side of the house and don't want to give you bad advice there. One would want a secret that is tethered to the lifetime of a successful login or from the user typing it in directly.

Item 1 - Tie to a PCR value only:

tpm2_startauthsession -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9" --policy=policy.dat
tpm2_flushcontext session.ctx

tpm2_nvdefine -C o --size=512 --policy=policy.dat --attributes='policyread|policywrite|read_stclear' $NV_INDEX

tpm2_startauthsession --policy -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9" 

echo 'secret' | tpm2_nvwrite -P'session:session.ctx' -i- $NV_INDEX
tpm2_flushcontext session.ctx

# should work
tpm2_startauthsession --policy -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
tpm2_nvread -P'session:session.ctx' -s6 $NV_INDEX
tpm2_flushcontext session.ctx

Item 2 - tie to PCR and user password:

NV_INDEX=0x01800000

set -e -o pipefail

tpm2_startauthsession -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9" 
tpm2_policypassword -S session.ctx --policy=policy.dat
tpm2_flushcontext session.ctx

tpm2_nvdefine -C o -p 'userpass' --size=512 --policy=policy.dat --attributes='policyread|policywrite|read_stclear' $NV_INDEX

tpm2_startauthsession --policy -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9" 
tpm2_policypassword -S session.ctx 

echo 'secret' | tpm2_nvwrite -P'session:session.ctx+userpass' -i- $NV_INDEX
tpm2_flushcontext session.ctx

tpm2_startauthsession --policy -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
tpm2_policypassword -S session.ctx
tpm2_nvread -P'session:session.ctx+userpass' -s6 $NV_INDEX
tpm2_flushcontext session.ctx

Item 3, add in recovery option.

#!/usr/bin/env bash

NV_INDEX=0x01800000

set -e -o pipefail

# this may not work for you, my TPM currently has an empty owner password
tpm2_changeauth -c o "ownerpass"

tpm2_startauthsession -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
tpm2_policypassword -S session.ctx --policy=policy.dat
tpm2_flushcontext session.ctx

tpm2_nvdefine -C o -P 'ownerpass' -p 'userpass' --size=512 --policy=policy.dat --attributes='ownerread|policyread|policywrite|read_stclear' $NV_INDEX

tpm2_startauthsession --policy -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
tpm2_policypassword -S session.ctx

echo 'secret' | tpm2_nvwrite -P'session:session.ctx+userpass' -i- $NV_INDEX
tpm2_flushcontext session.ctx

# recovery with owner password
tpm2_nvread -C o -P'ownerpass' -s6 $NV_INDEX

# normal flow, user auth
tpm2_startauthsession --policy -S session.ctx
tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
tpm2_policypassword -S session.ctx
tpm2_nvread -P'session:session.ctx+userpass' -s6 $NV_INDEX
tpm2_flushcontext session.ctx

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in my testing I found that when when you couple auth to a permanent object like owner hiearchy DA protections stop applying unless you authorize to the NV index and specify a bad authvalue.

ie

  • tpm2_nvread -Co -P garbage $NV_INDEX will not trigger DA protections.
  • tpm2_nvread -P badsession.ctx+badpass $NV_INDEX will not trigger DA protections.
  • tpm2_nvread -P session.ctx+badpass $NV_INDEX will trigger DA implications and protections.

I started looking at using policysecret to couple to the owner hiearchy via a policy OR to see if that would work, but I was unable to get the script to run and ran out of time, sharing here so you can perhaps figure it out. The manpage and test code for tpm2_policyor sucks, so I will bug @idesai to look at this.

#!/usr/bin/env bash

NV_INDEX=0x01800000

set -e -o pipefail

# this may not work for you, my TPM currently has an empty owner password
tpm2_changeauth -c o "ownerpass"

do_session() {
  # PCR + user auth
  tpm2_startauthsession -S session.ctx
  tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
  tpm2_policypassword -S session.ctx --policy=policy1.dat
  tpm2_flushcontext session.ctx

  # Tether to owner hiearchy auth, but not via attr so DA works
  tpm2_startauthsession -S session.ctx
  tpm2_policysecret -S session.ctx -c o --policy=policy2.dat 'ownerpass'
  tpm2_flushcontext session.ctx

  # create the OR policy of them both
  tpm2_startauthsession -S session.ctx
  tpm2_policyor -S session.ctx -lpolicy1.dat,policy2.dat -L policy.dat
}

do_session_user() {
  # PCR + user auth
  tpm2_startauthsession -S session.ctx --policy
  tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
  tpm2_policypassword -S session.ctx --policy=policy1.dat
  tpm2_flushcontext session.ctx

  # create the OR policy of them both
  tpm2_startauthsession -S session.ctx --policy
  tpm2_policyor -S session.ctx -lpolicy1.dat,policy2.dat
}

do_session
tpm2_nvdefine -C o -P 'ownerpass' -p 'userpass' --size=512 --policy=policy.dat --attributes='policyread|policywrite|read_stclear' $NV_INDEX
tpm2_flushcontext session.ctx

do_session_user
echo 'secret' | tpm2_nvwrite -P'session.ctx:session.ctx+userpass' -i- $NV_INDEX
tpm2_flushcontext session.ctx

# recovery with owner password
do_session_owner
tpm2_nvread -C o -P'ownerpass' -s6 $NV_INDEX

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in my testing I found that when when you couple auth to a permanent object like owner hiearchy DA protections stop applying unless you authorize to the NV index and specify a bad authvalue.

ie

  • tpm2_nvread -Co -P garbage $NV_INDEX will not trigger DA protections.
  • tpm2_nvread -P badsession.ctx+badpass $NV_INDEX will not trigger DA protections.
  • tpm2_nvread -P session.ctx+badpass $NV_INDEX will trigger DA implications and protections.

I started looking at using policysecret to couple to the owner hiearchy via a policy OR to see if that would work, but I was unable to get the script to run and ran out of time, sharing here so you can perhaps figure it out. The manpage and test code for tpm2_policyor sucks, so I will bug @idesai to look at this.

#!/usr/bin/env bash

NV_INDEX=0x01800000

set -e -o pipefail

# this may not work for you, my TPM currently has an empty owner password
tpm2_changeauth -c o "ownerpass"

do_session() {
  # PCR + user auth
  tpm2_startauthsession -S session.ctx
  tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
  tpm2_policypassword -S session.ctx --policy=policy1.dat
  tpm2_flushcontext session.ctx

  # Tether to owner hiearchy auth, but not via attr so DA works
  tpm2_startauthsession -S session.ctx
  tpm2_policysecret -S session.ctx -c o --policy=policy2.dat 'ownerpass'
  tpm2_flushcontext session.ctx

  # create the OR policy of them both
  tpm2_startauthsession -S session.ctx
  tpm2_policyor -S session.ctx -lpolicy1.dat,policy2.dat -L policy.dat
}

do_session_user() {
  # PCR + user auth
  tpm2_startauthsession -S session.ctx --policy
  tpm2_policypcr -S session.ctx --pcr-list="sha256:0,1,2,3,8,9"
  tpm2_policypassword -S session.ctx --policy=policy1.dat
  tpm2_flushcontext session.ctx

  # create the OR policy of them both
  tpm2_startauthsession -S session.ctx --policy
  tpm2_policyor -S session.ctx -lpolicy1.dat,policy2.dat
}

do_session
tpm2_nvdefine -C o -P 'ownerpass' -p 'userpass' --size=512 --policy=policy.dat --attributes='policyread|policywrite|read_stclear' $NV_INDEX
tpm2_flushcontext session.ctx

do_session_user
echo 'secret' | tpm2_nvwrite -P'session.ctx:session.ctx+userpass' -i- $NV_INDEX
tpm2_flushcontext session.ctx

# recovery with owner password
do_session_owner
tpm2_nvread -C o -P'ownerpass' -s6 $NV_INDEX

IIUC the requirement is that,

  1. We need an authentication policy for a sealing object that if fails should trigger the DA mechanism
  2. The authentication policy should be one of two — 1. PCR state 2. Recovery Password
  3. PCR state should have rollback protection
  4. TPM2_RH_OWNER auth should be used to update new PCR states and or the recovery password.

Copy link

@idesai idesai Jan 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@williamcroberts @ghfields this is one way to do what you are trying to achieve with enhanced authorization

NV Index always read policy

tpm2_startauthsession -S session.ctx
tpm2_policycountertimer -S session.ctx -L some.policy safe
tpm2_flushcontext session.ctx
tpm2_nvdefine -C o -s 34 -a "ownerwrite|policyread|authread" -L some.policy
-p recoverypass

PolicySecret NV Index --> Recovery Password == NV Index Password

dd if=/dev/urandom bs=1 count=34 status=none | tpm2_nvwrite -C o -i- 0x01000000
tpm2_startauthsession -S session.ctx
tpm2_policysecret -S session.ctx -L policy.secret.nvindex
-c 0x01000000 recoverypass
tpm2_flushcontext session.ctx

PolicyPCR

tpm2_startauthsession -S session.ctx
tpm2_policypcr -S session.ctx -l "sha1:0,1,2,3" -L policy.pcr
tpm2_flushcontext session.ctx

Policy ( PCR || Recovery-Password)

tpm2_startauthsession -S session.ctx
tpm2_policyor -S session.ctx -l sha256:policy.pcr,policy.secret.nvindex
-L policy.or
tpm2_flushcontext session.ctx

Policy written out to NV index with owner auth.

New PCR states will replace this value.

echo "000b" | xxd -p -r | cat - policy.or | tpm2_nvwrite -C o -i- 0x01000000
tpm2_startauthsession -S session.ctx
tpm2_policyauthorizenv -S session.ctx -L policy.authnv -C 0x01000000 0x01000000
-P recoverypass
tpm2_flushcontext session.ctx

Sealing object

tpm2_createprimary -C o -c prim.ctx -Q
echo "idesaisecret"| tpm2_create -Q -C prim.ctx -u key.pub -r key.priv
-a "fixedtpm|fixedparent|adminwithpolicy" -L policy.authnv -i-
tpm2_load -C prim.ctx -u key.pub -r key.priv -c key.ctx

Unsealing with PolicyPCR - Failing this triggers DA mechanism

tpm2_startauthsession -S session_read.ctx --policy-session
tpm2_policycountertimer -S session_read.ctx safe
tpm2_startauthsession -S session.ctx --policy-session
tpm2_policypcr -S session.ctx -l "sha1:0,1,2,3"
tpm2_policyor -S session.ctx -l sha256:policy.pcr,policy.secret.nvindex
tpm2_policyauthorizenv -S session.ctx -C 0x01000000 0x01000000
-P session:session_read.ctx
tpm2_unseal -c key.ctx -p session:session.ctx | xxd -p
tpm2_flushcontext session.ctx

Unsealing with Recovery-Password - Failing this triggers DA mechanism

tpm2_startauthsession -S session_read.ctx --policy-session
tpm2_policycountertimer -S session_read.ctx safe
tpm2_startauthsession -S session.ctx --policy-session
tpm2_policysecret -S session.ctx -L policy.secret.nvindex
-c 0x01000000 recoverypass
tpm2_policyor -S session.ctx -l sha256:policy.pcr,policy.secret.nvindex
tpm2_policyauthorizenv -S session.ctx -C 0x01000000 0x01000000
-P session:session_read.ctx
tpm2_unseal -c key.ctx -p session:session.ctx | xxd -p
tpm2_flushcontext session.ctx

echo "Note: Password storage can be verified with '--verifyonly' until reboot or locked manually with '--nvlockonly'."

# Store zfs filesystem properties
zfs set org.zfsonlinux.tpm2:index="$tpmindex" "${ENCRYPTIONROOT}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since you store the index, you might want to search for an open NV slot and use that rather than requiring a hard coded default or user to specify.

tpm2_getcap handles-nv-index

Will give you the current in use handles...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is true. Additionally, looking at the 4.1 changelog:
"tpm2_nvdefine: Support searching for free index if an index isn't specified."
If I bump the required version to 4.1+, I may be able to have tpm2_nvdefine do the work for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed tpm2-software/tpm2-tools#1891
I'd like to use tpm2_nvdefine to search for a usable index, but it offered an index not appropriate to the owner hierarchy as you showed in your spec document above.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is true. Additionally, looking at the 4.1 changelog:
"tpm2_nvdefine: Support searching for free index if an index isn't specified."
If I bump the required version to 4.1+, I may be able to have tpm2_nvdefine do the work for me.

Yeah it just starts at index 0, perhaps we should smarten that up.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to use tpm2_nvdefine to search for a usable index, but it offered an index not appropriate to the owner hierarchy as you showed in your spec document above.

Maybe add an option --search= which makes the argument the starting index and searches until stop is reached.

@ghfields
Copy link
Contributor Author

I want to thank @williamcroberts for taking the time to look at this. He is a regular voice on the tpm2 mailing list (tpm2@lists.01.org) and has been a great resource to me as I explored tpm2-tools.

@rlaager
Copy link
Member

rlaager commented Feb 9, 2020

The existing precedent is for org.open-zfs (with a dash) for property names.

Copy link
Member

@rlaager rlaager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few small comments. I wish I could be of more help on the TPM stuff. Awesome work!

@@ -0,0 +1,176 @@
#! /bin/bash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be plain /bin/sh? It looks like you have a bashism (or few) in here (I see a [[ ... ]]), but they could probably be fixed.

echo "Note: Password storage can be verified with '--verifyonly' until reboot or locked manually with '--nvlockonly'."

# Store zfs filesystem properties
zfs set org.zfsonlinux.tpm2:index="$tpmindex" "${ENCRYPTIONROOT}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is org.zfsonlinux. The PR description says org.openzfs. Existing practice for the latter is org.open-zfs.

copy_exec /usr/bin/tpm2_policypassword
copy_exec /usr/bin/tpm2_policypcr
copy_modules_dir kernel/drivers/char/tpm
copy_exec /usr/lib/x86_64-linux-gnu/libtss2-tcti-device.so.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the tpm2 tools x86_64 only? (I could see how they might be, though they probably also work on x32 and maybe work in i386?) If not, then the architecture here should probably be detected.

@Rudd-O
Copy link
Contributor

Rudd-O commented Apr 14, 2020

Half of this code should probably be rewritten as a Clevis PIN or simply discarded, since Clevis already ships with (reviewed) TPM 2.0 support. The other half should be added to Clevis so that Clevis learns how to unlock ZFS datasets. If added to Clevis / upstreamed as a PIN, it will work across all distributions.

https://github.com/latchset/clevis

EDIT: someone already started to use Clevis to do exactly this: https://www.reddit.com/r/zfs/comments/dimtjv/guide_setting_up_tpm2based_decryption_for_zfs_on/

@illiliti illiliti mentioned this pull request Jun 2, 2020
19 tasks
Signed-off-by: Garrett Fields <ghfields@gmail.com>
@almereyda
Copy link

To follow up on using Clevis for TPM support to unlock encryptionroots, there are now also this issue and this PR available at upstream:

@ghost
Copy link

ghost commented Dec 1, 2022

Half of this code should probably be rewritten as a Clevis PIN or simply discarded, since Clevis already ships with (reviewed) TPM 2.0 support. The other half should be added to Clevis so that Clevis learns how to unlock ZFS datasets. If added to Clevis / upstreamed as a PIN, it will work across all distributions.

https://github.com/latchset/clevis

EDIT: someone already started to use Clevis to do exactly this: https://www.reddit.com/r/zfs/comments/dimtjv/guide_setting_up_tpm2based_decryption_for_zfs_on/

This is being done by @techhazard already, not sure why the repetition of efforts, but he has a working pull request AFAIK (for Clevis).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Design Review Needed Architecture or design is under discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants