~nabijaczleweli/tzpfms

6ae9df1c95eec6a6a0e35b8807a07a8285c5e6e6 — наб a month ago 5b0685e
Rewrite manual in mdoc
23 files changed, 947 insertions(+), 381 deletions(-)

M .build.yml
M Makefile
M README.md
M configMakefile
M man/backend-tpm1x.h
M man/backend-tpm2.h
M man/common.h
D man/index.txt
A man/style.css
A man/zfs-tpm-list.8.pp
D man/zfs-tpm-list.md.pp
A man/zfs-tpm1x-change-key.8.pp
D man/zfs-tpm1x-change-key.md.pp
A man/zfs-tpm1x-clear-key.8.pp
D man/zfs-tpm1x-clear-key.md.pp
A man/zfs-tpm1x-load-key.8.pp
D man/zfs-tpm1x-load-key.md.pp
A man/zfs-tpm2-change-key.8.pp
D man/zfs-tpm2-change-key.md.pp
A man/zfs-tpm2-clear-key.8.pp
D man/zfs-tpm2-clear-key.md.pp
A man/zfs-tpm2-load-key.8.pp
D man/zfs-tpm2-load-key.md.pp
M .build.yml => .build.yml +40 -2
@@ 8,9 8,12 @@ packages:
  - pkg-config
  - libtss2-dev
  - libtspi-dev
  - ronn
  - mandoc
  - shellcheck
  - curl
  - groff
  - ghostscript
  - gsfonts
tasks:
  - get-zfs: |
      sudo sed -i 's/main/main contrib non-free/' /etc/apt/sources.list


@@ 25,12 28,45 @@ tasks:
      cd tzpfms
      CC=clang CXX=clang++ make
      find out/ -maxdepth 1 -type f -exec readelf -d {} +
  # https://nabijaczleweli.xyz/content/blogn_t/007-groff-Tps-cyrillic-et-al.html
  - prep-fonts: |
      mkdir /tmp/devps; cd /tmp/devps
      for f in {C,T}{R,B,I,BI}; do
        in="$(awk '$1 == "internalname" {print $2; exit}' "/usr/share/groff/current/font/devps/$f")";
        echo $f: $in;
        src="$(awk -v cur="/$in" '
          $1 ~ /^\// && $2 ~ /^[\/\(]/ {
            if($2 ~ /^\//)
              aliases[$1] = $2;
            else
              paths[$1] = $2;
          }
          END {
            while(cur in aliases)
              cur = aliases[cur];
            if(cur in paths) {
              sub(/^\(/, "", paths[cur]);
              sub(/(pfb)?\)$/, "", paths[cur]);
              print paths[cur]
            } else {
              print "last: " cur > "/dev/stderr";
              exit 1
            }
          }' /var/lib/ghostscript/fonts/Fontmap)";
        echo ${src}afm;
        afmtodit $(expr "$f" : C > /dev/null && printf -- -n) -cmi0 \
          -d /usr/share/groff/current/font/devps/DESC \
          -e /usr/share/groff/current/font/devps/text.enc \
          "${src}afm" /usr/share/groff/current/font/devps/generate/textmap "$f";
      done
  - manpages: |
      git -C tzpfms/ worktree add ../tzpfms-man man
      cd tzpfms-man
      git ls-tree -z --name-only HEAD | xargs -0 rm -r
      cp -pr ../tzpfms/out/man/* .
      git add .
      sed -e 's/…/.../g' $(ls *.[12345678] | awk -F. '{print $2 "\t" $1}' | sort | awk -F'\t' '{print $2 "." $1}') | groff -K utf8 -tpe -mdoc -Tps > tzpfms.ps
      ps2pdf tzpfms.ps tzpfms.pdf
      git config user.email "nabijaczleweli/autouploader@nabijaczleweli.xyz"
      git config user.name "наб autouploader"
      git commit -m "Manpage update by job $JOB_ID" || exit 0


@@ 45,11 81,13 @@ tasks:
      mv tzpfms/out/dracut          "tzpfms-$tag-dracut"
      mv tzpfms/out/initramfs-tools "tzpfms-$tag-initramfs-tools"
      mv tzpfms/out/man             "tzpfms-$tag-man"
      mv tzpfms-man/tzpfms.ps       "tzpfms-$tag-manual.ps"
      mv tzpfms-man/tzpfms.pdf      "tzpfms-$tag-manual.pdf"
      for s in bin-amd64 dracut initramfs-tools man; do
        tar -caf "tzpfms-$tag-$s.tbz2" "tzpfms-$tag-$s"
      done
      set +x  # Avoid echoing the token
      for f in *.tbz2; do
      for f in *.tbz2 "tzpfms-$tag-manual.ps" "tzpfms-$tag-manual.pdf"; do
        curl -H "Authorization: Bearer $(cat ~/.release-token)" \
             -XPOST                                             \
             -F "file=@$f"                                      \

M Makefile => Makefile +23 -14
@@ 31,15 31,15 @@ VERAR := $(foreach l,TZPFMS,-D$(l)_VERSION='$($(l)_VERSION)')
BINARY_SOURCES := $(sort $(wildcard $(SRCDIR)bin/*.cpp $(SRCDIR)bin/**/*.cpp))
COMMON_SOURCES := $(filter-out $(BINARY_SOURCES),$(sort $(wildcard $(SRCDIR)*.cpp $(SRCDIR)**/*.cpp $(SRCDIR)**/**/*.cpp $(SRCDIR)**/**/**/*.cpp)))
MANPAGE_HEADERS := $(sort $(wildcard $(MANDIR)*.h))
MANPAGE_SOURCES := $(sort $(wildcard $(MANDIR)*.md.pp))
MANPAGE_SOURCES := $(sort $(wildcard $(MANDIR)*.[012345678].pp))
INITRD_HEADERS := $(sort $(wildcard $(INITRDDIR)*.h))


.PHONY : all clean build shellcheck i-t dracut man
.PHONY : all clean build shellcheck i-t dracut manpages htmlpages
.SECONDARY:


all : build man shellcheck i-t dracut
all : build manpages htmlpages shellcheck i-t dracut

shellcheck : i-t dracut
	find $(OUTDIR)initramfs-tools/ $(OUTDIR)dracut -name '*.sh' -exec echo $(SHELLCHECK) --exclude SC1091 {} + | sh -x


@@ 48,17 48,12 @@ clean :
	rm -rf $(OUTDIR)

build : $(subst $(SRCDIR)bin/,$(OUTDIR),$(subst .cpp,$(EXE),$(BINARY_SOURCES)))
man : $(OUTDIR)man/index.txt
manpages : $(patsubst $(MANDIR)%.pp,$(OUTDIR)man/%,$(MANPAGE_SOURCES))
htmlpages : $(patsubst $(MANDIR)%.pp,$(OUTDIR)man/%.html,$(MANPAGE_SOURCES)) $(OUTDIR)man/style.css
i-t : $(OUTDIR)initramfs-tools/usr/share/initramfs-tools/hooks/tzpfms $(OUTDIR)initramfs-tools/usr/share/tzpfms/initramfs-tools-zfs-patch.sh
dracut : $(patsubst $(INITRDDIR)dracut/%,$(OUTDIR)dracut/usr/lib/dracut/modules.d/91tzpfms/%,$(sort $(wildcard $(INITRDDIR)dracut/*.sh)))


$(OUTDIR)man/index.txt : $(MANDIR)index.txt $(patsubst $(MANDIR)%.pp,$(OUTDIR)man/%,$(MANPAGE_SOURCES))
	@mkdir -p $(dir $@)
	cp $< $(dir $@)
	$(RONN) --organization="tzpfms developers"    $(filter-out $<,$^)
	$(RONN) --organization="tzpfms developers" -f $(filter-out $<,$^)

$(OUTDIR)initramfs-tools/usr/share/initramfs-tools/hooks/tzpfms: $(INITRDDIR)initramfs-tools/hook $(INITRD_HEADERS)
	@mkdir -p $(dir $@)
	$(AWK) -f pp.awk $< > $@


@@ 69,6 64,24 @@ $(OUTDIR)initramfs-tools/usr/share/tzpfms/initramfs-tools-zfs-patch.sh: $(INITRD
	$(AWK) -f pp.awk $< > $@
	chmod --reference $< $@

# The d-v-o-s string starts at "BSD" (hence the "BSD General Commands Manual" default); we're not BSD, so hide it
# Can't put it at the very top, since man(1) only loads mdoc *after* the first mdoc macro (.Dd in our case)
$(OUTDIR)man/% : $(MANDIR)%.pp $(MANPAGE_HEADERS)
	@mkdir -p $(dir $@)
	( cd $(dir $<) && $(CXX) -Wno-invalid-pp-token -E - ) < $< | $(AWK) '/^$$/ {prev_empty=1; next} $$1 == "#" && $$2 ~ /^[0-9]*$$/ {prev_empty=0; next}  {if(prev_empty) print ""; prev_empty=0; print}' | $(AWK) '$$0 == ".Dd" {$$2 = "$(TZPFMS_DATE)"}  $$1 == ".Dt" { print ".ds doc-volume-operating-system" }  $$0 == ".Os" {$$2 = "tzpfms"; $$3 = "$(TZPFMS_VERSION)"}  {print}' > $@
	! $(MANDOC) -Tlint $@ 2>&1 | grep -vE -e 'mandoc: outdated mandoc.db' -e 'STYLE: referenced manual not found' -e 'STYLE: operating system explicitly specified: Os tzpfms' -e 'WARNING: cross reference to self: Xr zfs-tpm.*-change-key 8'
# The "WARNING: unknown font, skipping request: TS.+fC[RBI]" one: see https://bugs.debian.org/992002

$(OUTDIR)man/%.html : $(OUTDIR)man/%
	@mkdir -p $(dir $@)
	( cd $(OUTDIR)man/ && $(MANDOC) -Thtml -Ostyle="style.css",man="%N.%S.html;https://manpages.debian.org/bullseye/%N.%S" ) < $< | \
		$(AWK) '/^<h1/ {in_syn = $$0 ~ /id="SYNOPSIS"/}  /^<br/ {if(in_syn) next}  {print}' | \
		$(SED) -Ee 's/ title=".."//g' -e 's/<a class="permalink" href="#([^"]*)"><span class="No" id="([^"]*)">/<a><span class="No">/g' -e 's#manpages.debian.org/[^/]*/ESYS_CONTEXT.3#mankier.com/3/ESYS_CONTEXT#g' > $@

$(OUTDIR)man/style.css : man/style.css
	@mkdir -p $(dir $@)
	cp $^ $@


$(OUTDIR)%$(EXE) : $(subst $(SRCDIR),$(OBJDIR),$(subst .cpp,$(OBJ),$(SRCDIR)bin/%.cpp $(COMMON_SOURCES)))
	@mkdir -p $(dir $@)


@@ 83,10 96,6 @@ $(BLDDIR)test/%$(OBJ) : $(TSTDIR)%.cpp
	@mkdir -p $(dir $@)
	$(CXX) $(CXXAR) $(INCAR) -I$(SRCDIR) $(VERAR) -c -o$@ $^

$(OUTDIR)man/%.md : $(MANDIR)%.md.pp $(MANPAGE_HEADERS)
	@mkdir -p $(dir $@)
	$(AWK) -f pp.awk $< > $@

$(OUTDIR)dracut/usr/lib/dracut/modules.d/91tzpfms/% : $(INITRDDIR)dracut/% $(INITRD_HEADERS)
	@mkdir -p $(dir $@)
	$(AWK) -f pp.awk $< > $@

M README.md => README.md +6 -5
@@ 1,7 1,7 @@
# tzpfms [![builds.sr.ht badge](//builds.sr.ht/~nabijaczleweli/tzpfms.svg)](https://builds.sr.ht/~nabijaczleweli/tzpfms) [![Licence](//img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
TPM-based encryption keys for ZFS datasets.

## [Manpages](//git.sr.ht/~nabijaczleweli/tzpfms/tree/man)
## [Manpages](//srhtcdn.githack.com/~nabijaczleweli/tzpfms/blob/man/zfs-tpm-list.8.html) ([PDF](//srhtcdn.githack.com/~nabijaczleweli/tzpfms/blob/man/tzpfms.pdf))

### Why?



@@ 23,9 23,11 @@ and initramfs-tools (with/without Plymouth) are supported for [ZFS-on-root](http

### Building

You'll need `pkg-config`, `ronn`, `shellcheck`, `libzfslinux-dev` (0.8.x and 2.0.x work), `libtss2-dev`, `libtspi-dev`, and `make` should hopefully Just Work™ if you have a C++17-capable compiler.
You'll need `pkg-config`, `shellcheck`, `libzfslinux-dev` (0.8.x and 2.0.x work), `libtss2-dev`, `libtspi-dev`, and `make` should hopefully Just Work™ if you have a C++17-capable compiler.
The output binaries are trimmed of extraneous dependencies, so they're all just libc + libzfs and friends + the chosen TPM back-end, if any.

`mandoc` is required for HTML manuals. Set `MANDOC=true` to forgo this.

### Installation

Copy the `out/zfs-tpm*` binaries corresponding to the back-ends you want to `/sbin`,


@@ 44,9 46,8 @@ deb https://debian.nabijaczleweli.xyz sid main

With [my PGP key](//nabijaczleweli.xyz/pgp.txt) (the two URLs are interchangeable):
```sh
wget -O- https://debian.nabijaczleweli.xyz/nabijaczleweli.gpg.key | sudo apt-key add
# or
sudo wget -O/etc/apt/trusted.gpg.d/nabijaczleweli.asc //keybase.io/nabijaczleweli/pgp_keys.asc
sudo wget -O/etc/apt/trusted.gpg.d/nabijaczleweli.asc https://debian.nabijaczleweli.xyz/nabijaczleweli.gpg.key
sudo wget -O/etc/apt/trusted.gpg.d/nabijaczleweli.asc https://keybase.io/nabijaczleweli/pgp_keys.asc
```

Then the usual

M configMakefile => configMakefile +3 -1
@@ 47,12 47,14 @@ else
endif

TZPFMS_VERSION := "$(patsubst v%,%,$(shell git describe))"
TZPFMS_DATE := $(shell date -d@$$(git log --no-show-signature -1 --pretty=%at) '+%B %e, %Y')

INCCMAKEAR := CXXFLAGS="$(INCCXXAR)"
LNCMAKEAR := LDFLAGS="$(LNCXXAR)"

AWK ?= awk
RONN ?= ronn
SED ?= sed
MANDOC ?= mandoc
SHELLCHECK ?= shellcheck
OBJ := .o
CXXAR := -O3 -std=c++17 -fno-exceptions -Wall -Wextra $(CXXSPECIFIC) -pipe $(INCCXXAR) $(PIC)

M man/backend-tpm1x.h => man/backend-tpm1x.h +28 -14
@@ 1,15 1,29 @@
## TPM1.X back-end configuration

### TPM selection

The tzpfms suite connects to a local tcsd(8) process (at `localhost:30003`) by default.
Use the environment variable `TZPFMS_TPM1X` to specify a remote TCS hostname.

The TrouSerS tcsd(8) daemon will try `/dev/tpm0`, then `/udev/tpm0`, then `/dev/tpm`;
.Sh TPM1.X back-end configuration
.Ss TPM selection
The
.Nm tzpfms
suite connects to a local
.Xr tcsd 8
process
.Pq at Pa localhost:30003
by default.
Use the environment variable
.Ev TZPFMS_TPM1X
to specify a remote TCS hostname.
.Pp
The TrouSerS
.Xr tcsd 8
daemon will try
.Pa /dev/tpm0 ,
then
.Pa /udev/tpm0 ,
then
.Pa /dev/tpm ;
by occupying one of the earlier ones with, for example, shell redirection, a later one can be selected.

### See also

The TrouSerS project page at <https://sourceforge.net/projects/trousers>.

The TPM 1.2 main specification index at &lt;<https://trustedcomputinggroup.org/resource/tpm-main-specification>&gt;.
.
.Ss See also
The TrouSerS project page at
.Lk https:/\&/sourceforge.net/projects/trousers .
.Pp
The TPM 1.2 main specification index at
.Lk https:/\&/trustedcomputinggroup.org/resource/tpm-main-specification .

M man/backend-tpm2.h => man/backend-tpm2.h +33 -17
@@ 1,17 1,33 @@
## TPM2 back-end configuration

### Environment variables

  * `TSS2_LOG`=:
    Any of: *NONE*, *ERROR*, *WARNING*, *INFO*, *DEBUG*, *TRACE*. Default: *WARNING*.

### TPM selection

The library `libtss2-tcti-default.so` can be linked to any of the `libtss2-tcti-*.so` libraries to select the default,
otherwise `/dev/tpmrm0`, then `/dev/tpm0`, then `localhost:2321` will be tried, in order (see ESYS_CONTEXT(3)).

### See also

The tpm2-tss git repository at <https://github.com/tpm2-software/tpm2-tss> and the documentation at <https://tpm2-tss.readthedocs.io>.

The TPM 2.0 specifications, mainly at &lt;<https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf>&gt; and related pages.
.Sh TPM2 back-end configuration
.Ss Environment variables
.Bl -tag -compact -width "TSS2_LOG"
.It Ev TSS2_LOG
Any of:
.Sy NONE , ERROR , WARNING , INFO , DEBUG , TRACE .
Default:
.Sy WARNING .
.El
.
.Ss TPM selection
The library
.Nm libtss2-tcti-default.so
can be linked to any of the
.Pa libtss2-tcti-*.so
libraries to select the default, otherwise
.Pa /dev/tpmrm0 ,
then
.Pa /dev/tpm0 ,
then
.Pa localhost:2321
will be tried, in order
.Pq see Xr ESYS_CONTEXT 3 .
.
.Ss See also
The tpm2-tss git repository at
.Lk https:/\&/github.com/tpm2-software/tpm2-tss
and the documentation at
.Lk https:/\&/tpm2-tss.readthedocs.io .
.Pp
The TPM 2.0 specifications, mainly at
.Lk https:/\&/trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf
and related pages.

M man/common.h => man/common.h +18 -15
@@ 1,16 1,19 @@
## AUTHOR

Written by наб &lt;<nabijaczleweli@nabijaczleweli.xyz>&gt;

## SPECIAL THANKS

.Sh AUTHORS
Written by
.An наб Aq nabijaczleweli@nabijaczleweli.xyz .
.
.Sh SPECIAL THANKS
To all who support further development, in particular:

  * ThePhD
  * Embark Studios

## REPORTING BUGS

&lt;<https://todo.sr.ht/~nabijaczleweli/tzpfms>&gt;

&lt;<mailto:~nabijaczleweli/tzpfms@lists.sr.ht>&gt;, archived at &lt;<https://lists.sr.ht/~nabijaczleweli/tzpfms>&gt;
.Bl -bullet -offset 4n -compact -width 0
.It
ThePhD
.It
Embark Studios
.El
.
.Sh REPORTING BUGS
.Lk https:/\&/todo.sr.ht/~nabijaczleweli/tzpfms
.Pp
.Mt ~nabijaczleweli/tzpfms@lists.sr.ht ,
archived at
.Lk https:/\&/lists.sr.ht/~nabijaczleweli/tzpfms .

D man/index.txt => man/index.txt +0 -13
@@ 1,13 0,0 @@
zfs-tpm2-change-key(8)   zfs-tpm2-change-key.8.ronn
zfs-tpm2-load-key(8)     zfs-tpm2-load-key.8.ronn
zfs-tpm2-clear-key(8)    zfs-tpm2-clear-key.8.ronn
zfs-tpm1x-change-key(8)  zfs-tpm1x-change-key.8.ronn
zfs-tpm1x-load-key(8)    zfs-tpm1x-load-key.8.ronn
zfs-tpm1x-clear-key(8)   zfs-tpm1x-clear-key.8.ronn
zfs-tpm-list(8)          zfs-tpm-list.8.ronn

zfs(8)                   https://manpages.debian.org/bullseye/zfsutils-linux/zfs.8.en.html
tcsd(8)                  https://manpages.debian.org/bullseye/trousers/tcsd.8.en.html
tpm2_unseal(1)           https://manpages.debian.org/bullseye/tpm2-tools/tpm2_unseal.1.en.html

ESYS_CONTEXT(3)          https://www.mankier.com/3/ESYS_CONTEXT

A man/style.css => man/style.css +297 -0
@@ 0,0 1,297 @@
/* $OpenBSD: mandoc.css,v 1.33 2019/06/02 16:50:46 schwarze Exp $ */
/*
 * Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
 *
 * Written by Ingo Schwarze <schwarze@openbsd.org>.
 * I place this file into the public domain.
 * Permission to use, copy, modify, and distribute it for any purpose
 * with or without fee is hereby granted, without any conditions.
 */
/* Tooltips removed. */

/* Global defaults. */

html {		max-width: 65em;
		--bg: #FFFFFF;
		--fg: #000000; }
body {		background: var(--bg);
		color: var(--fg);
		font-family: Helvetica,Arial,sans-serif; }
h1 {		font-size: 110%; }
table {		margin-top: 0em;
		margin-bottom: 0em;
		border-collapse: collapse; }
/* Some browsers set border-color in a browser style for tbody,
 * but not for table, resulting in inconsistent border styling. */
tbody {		border-color: inherit; }
tr {		border-color: inherit; }
td {		vertical-align: top;
		padding-left: 0.2em;
		padding-right: 0.2em;
		border-color: inherit; }
ul, ol, dl {	margin-top: 0em;
		margin-bottom: 0em; }
li, dt {	margin-top: 1em; }

.permalink {	border-bottom: thin dotted;
		color: inherit;
		font: inherit;
		text-decoration: inherit; }
* {		clear: both }

/* Search form and search results. */

fieldset {	border: thin solid silver;
		border-radius: 1em;
		text-align: center; }
input[name=expr] {
		width: 25%; }

table.results {	margin-top: 1em;
		margin-left: 2em;
		font-size: smaller; }

/* Header and footer lines. */

table.head {	width: 100%;
		border-bottom: 1px dotted #808080;
		margin-bottom: 1em;
		font-size: smaller; }
td.head-vol {	text-align: center; }
td.head-rtitle {
		text-align: right; }

table.foot {	width: 100%;
		border-top: 1px dotted #808080;
		margin-top: 1em;
		font-size: smaller; }
td.foot-os {	text-align: right; }

/* Sections and paragraphs. */

.manual-text {
		margin-left: 3.8em; }
.Nd { }
section.Sh { }
h1.Sh {		margin-top: 1.2em;
		margin-bottom: 0.6em;
		margin-left: -3.2em; }
section.Ss { }
h2.Ss {		margin-top: 1.2em;
		margin-bottom: 0.6em;
		margin-left: -1.2em;
		font-size: 105%; }
.Pp {		margin: 0.6em 0em; }
.Sx { }
.Xr { }

/* Displays and lists. */

.Bd { }
.Bd-indent {	margin-left: 3.8em; }

.Bl-bullet {	list-style-type: disc;
		padding-left: 1em; }
.Bl-bullet > li { }
.Bl-dash {	list-style-type: none;
		padding-left: 0em; }
.Bl-dash > li:before {
		content: "\2014  "; }
.Bl-item {	list-style-type: none;
		padding-left: 0em; }
.Bl-item > li { }
.Bl-compact > li {
		margin-top: 0em; }

.Bl-enum {	padding-left: 2em; }
.Bl-enum > li { }
.Bl-compact > li {
		margin-top: 0em; }

.Bl-diag { }
.Bl-diag > dt {
		font-style: normal;
		font-weight: bold; }
.Bl-diag > dd {
		margin-left: 0em; }
.Bl-hang { }
.Bl-hang > dt { }
.Bl-hang > dd {
		margin-left: 5.5em; }
.Bl-inset { }
.Bl-inset > dt { }
.Bl-inset > dd {
		margin-left: 0em; }
.Bl-ohang { }
.Bl-ohang > dt { }
.Bl-ohang > dd {
		margin-left: 0em; }
.Bl-tag {	margin-top: 0.6em;
		margin-left: 5.5em; }
.Bl-tag > dt {
		float: left;
		margin-top: 0em;
		margin-left: -5.5em;
		padding-right: 0.5em;
		vertical-align: top; }
.Bl-tag > dd {
		clear: right;
		column-count: 1;  /* Force block formatting context. */
		width: 100%;
		margin-top: 0em;
		margin-left: 0em;
		margin-bottom: 0.6em;
		vertical-align: top; }
.Bl-compact {	margin-top: 0em; }
.Bl-compact > dd {
		margin-bottom: 0em; }
.Bl-compact > dt {
		margin-top: 0em; }

.Bl-column { }
.Bl-column > tbody > tr { }
.Bl-column > tbody > tr > td {
		margin-top: 1em; }
.Bl-compact > tbody > tr > td {
		margin-top: 0em; }

.Rs {		font-style: normal;
		font-weight: normal; }
.RsA { }
.RsB {		font-style: italic;
		font-weight: normal; }
.RsC { }
.RsD { }
.RsI {		font-style: italic;
		font-weight: normal; }
.RsJ {		font-style: italic;
		font-weight: normal; }
.RsN { }
.RsO { }
.RsP { }
.RsQ { }
.RsR { }
.RsT {		text-decoration: underline; }
.RsU { }
.RsV { }

.eqn { }
.tbl td {	vertical-align: middle; }

.HP {		margin-left: 3.8em;
		text-indent: -3.8em; }

/* Semantic markup for command line utilities. */

table.Nm { }
code.Nm {	font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Fl {		font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Cm {		font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Ar {		font-style: italic;
		font-weight: normal;
		font-family: monospace; }
.Op {		display: inline; }
.Ic {		font-style: normal;
		font-weight: bold;
		font-family: monospace; }
.Ev {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }
.Pa {		font-style: italic;
		font-weight: normal; }

/* Semantic markup for function libraries. */

.Lb { }
code.In {	font-style: normal;
		font-weight: bold;
		font-family: inherit; }
a.In { }
.Fd {		font-style: normal;
		font-weight: bold;
		font-family: inherit; }
.Ft {		font-style: italic;
		font-weight: normal; }
.Fn {		font-style: normal;
		font-weight: bold;
		font-family: inherit; }
.Fa {		font-style: italic;
		font-weight: normal; }
.Vt {		font-style: italic;
		font-weight: normal; }
.Va {		font-style: italic;
		font-weight: normal; }
.Dv {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }
.Er {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }

/* Various semantic markup. */

.An { }
.Lk { }
.Mt { }
.Cd {		font-style: normal;
		font-weight: bold;
		font-family: inherit; }
.Ad {		font-style: italic;
		font-weight: normal; }
.Ms {		font-style: normal;
		font-weight: bold; }
.St { }
.Ux { }

/* Physical markup. */

.Bf {		display: inline; }
.No {		font-style: normal;
		font-weight: normal; }
.Em {		font-style: italic;
		font-weight: normal; }
.Sy {		font-style: normal;
		font-weight: bold; }
.Li {		font-style: normal;
		font-weight: normal;
		font-family: monospace; }

/* Tooltip support. */

h1.Sh, h2.Ss {	position: relative; }
.Li, .An, .Ar, .Cd, .Cm, .Dv, .Em, .Er, .Ev, .Fa, .Fd, .Fl, .Fn, .Ft,
.Ic, code.In, .Lb, .Lk, .Ms, .Mt, .Nd, code.Nm, .Pa, .Rs,
.St, .Sx, .Sy, .Va, .Vt, .Xr {
		display: inline-block;
		position: relative; }

/* Overrides to avoid excessive margins on small devices. */

@media (max-width: 37.5em) {
.manual-text {
		margin-left: 0.5em; }
h1.Sh, h2.Ss {	margin-left: 0em; }
.Bd-indent {	margin-left: 2em; }
.Bl-hang > dd {
		margin-left: 2em; }
.Bl-tag {	margin-left: 2em; }
.Bl-tag > dt {
		margin-left: -2em; }
.HP {		margin-left: 2em;
		text-indent: -2em; }
}

/* Overrides for a dark color scheme for accessibility. */

@media (prefers-color-scheme: dark) {
html {		--bg: #1E1F21;
		--fg: #EEEFF1; }
:link {		color: #BAD7FF; }
:visited {	color: #F6BAFF; }
}

A man/zfs-tpm-list.8.pp => man/zfs-tpm-list.8.pp +120 -0
@@ 0,0 1,120 @@
.Dd
.Dt ZFS-TPM-LIST 8
.Os
.
.Sh NAME
.Nm zfs-tpm-list
.Nd print dataset tzpfms metadata
.Sh SYNOPSIS
.Nm
.Op Fl H
.Op Fl r Ns \&| Ns Fl d Ar depth
.Op Fl a Ns \&| Ns Fl b Ar back-end
.Op Fl u Ns \&| Ns Fl l
.Oo Ar filesystem Ns \&| Ns Ar volume Oc Ns …
.
.Sh DESCRIPTION
Lists the following properties on encryption roots:
.Bl -tag -compact -offset Ds -width "keystatus"
.It Li name
.It Li back-end
the
.Nm tzpfms
back-end
.Pq e.g. Sy TPM2 No for Xr zfs-tpm2-change-key 8 or Sy TPM1.X No for Xr zfs-tpm1x-change-key 8 ,
or
.Qq Sy -
if none is configured
.It Li keystatus
.Sy available
or
.Sy unavailable
.It Li coherent
.Sy yes
if either both
.Li xyz.nabijaczleweli:tzpfms.backend
and
.Li xyz.nabijaczleweli:tzpfms.key
are present or missing,
.Sy no
otherwise
.El
.Pp
Incoherent datasets require immediate operator attention, with either the appropriate
.Nm zfs-tpm*-clear-key
program or
.Nm zfs Cm change-key
and
.Nm zfs Cm inherit
\(em if the key becomes unloaded, they will require restoration from back-up.
However, they should never occur, unless something went terribly wrong with the dataset properties.
.Pp
If no datasets are specified, lists all matching encryption roots.
The default filter is to list all roots managed by
.Nm tzpfms .
.Fl ab
can be used to either list all roots or only ones backed by a particular end, respectively.
.
.Sh OPTIONS
.Bl -tag -compact -width "-b back-end"
.It Fl H
Scripting mode \(em do not print headers and separate fields by a single tab instead of columnating with spaces.
.Pp
.It Fl r
Recurse into all descendants of specified datasets.
.It Fl d Ar depth
Recurse at most
.Ar depth
datasets deep.
Default:
.Sy 0 .
.Pp
.It Fl a
List all encryption roots, even ones not managed by
.Nm tzpfms .
.It Fl b Ar back-end
List only encryption roots with
.Ar tzpfms
back-end
.Ar back-end .
.Pp
.It Fl l
List only encryption roots whose keys are available.
.It Fl y
List only encryption roots whose keys are unavailable.
.El
.
.Sh EXAMPLES
.Bd -literal -compact
.Li $ Nm
NAME      BACK-END  KEYSTATUS    COHERENT
owo/venc  TPM2      unavailable  yes
owo/enc   TPM1.X    available    yes

.Li $ Nm Fl ad0
NAME  BACK-END  KEYSTATUS  COHERENT
awa   -         available  yes

.Li $ Nm Fl b Sy TPM2
NAME      BACK-END  KEYSTATUS    COHERENT
owo/venc  TPM2      unavailable  yes

.Li $ Nm Fl ra Ar owo
NAME      BACK-END  KEYSTATUS    COHERENT
owo/venc  TPM2      unavailable  yes
owo/vtnc  -         available    yes
owo/v nc  -         available    yes
owo/enc   TPM1.X    available    yes

.Li $ Nm Fl al
NAME      BACK-END  KEYSTATUS  COHERENT
awa       -         available  yes
owo/vtnc  -         available  yes
owo/v nc  -         available  yes
owo/enc   TPM1.X    available  yes
.Ed
.
#include "common.h"
.
.Sh SEE ALSO
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm-list.md.pp => man/zfs-tpm-list.md.pp +0 -80
@@ 1,80 0,0 @@
zfs-tpm-list(8) -- print dataset tzpfms metadata
================================================

## SYNOPSIS

`zfs-tpm-list` [-H] [-r\|-d *depth*] [-a\|-b *back-end*] [-u\|-l] [*filesystem*\|*volume*]…

## DESCRIPTION

zfs-tpm-list(8) lists the following properties on encryption roots:

  * `name`,
  * `back-end`: the tzpfms back-end (e.g. "TPM2" for zfs-tpm2-change-key(8) or "TPM1.X" for zfs-tpm1x-change-key(8)),
                or "-" if none is configured,
  * `keystatus`: "available" or "unavailable",
  * `coherent`: "yes" if either both `xyz.nabijaczleweli:tzpfms.backend` and `xyz.nabijaczleweli:tzpfms.key` are present or missing, "no" otherwise.

Incoherent datasets require immediate operator attention, with either the appropriate zfs-tpm\*-clear-key program or zfs(8) change-key and zfs(8) inherit —
if the key becomes unloaded, they will require restoration from back-up.
However, they should never occur, unless something went terribly wrong with the dataset properties.

If no datasets are specified, lists all matching encryption roots.
The default filter is to list all roots managed by tzpfms.
The `-a` and `-b` [OPTIONS]() can be used to either list all roots or only ones backed by a particular end, respectively.

## OPTIONS

  * `-H`:
    Used for scripting mode. Do not print headers and separate fields by a single tab instead of arbitrary white space.

  * `-r`:
    Recurse into all descendant datasets. Default if no datasets listed on the command-line.
  * `-d` *depth*:
    Recurse at most *depth* datasets deep. Defaults to zero if datasets were listed on the command-line.

  * `-a`:
    List all encryption roots, even ones not managed by tzpfms.
  * `-b` *back-end*:
    List only encryption roots with tzpfms back-end *back-end*.

  * `-l`:
    List only encryption roots whose keys are available.
  * `-u`:
    List only encryption roots whose keys are unavailable.

## EXAMPLES

    $ zfs-tpm-list
    NAME      BACK-END  KEYSTATUS    COHERENT
    owo/venc  TPM2      unavailable  yes
    owo/enc   TPM1.X    available    yes

    $ zfs-tpm-list -ad0
    NAME  BACK-END  KEYSTATUS  COHERENT
    awa   -         available  yes

    $ zfs-tpm-list -b TPM2
    NAME      BACK-END  KEYSTATUS    COHERENT
    owo/venc  TPM2      unavailable  yes

    $ zfs-tpm-list -ra owo
    NAME      BACK-END  KEYSTATUS    COHERENT
    owo/venc  TPM2      unavailable  yes
    owo/vtnc  -         available    yes
    owo/v nc  -         available    yes
    owo/enc   TPM1.X    available    yes

    $ zfs-tpm-list -al
    NAME      BACK-END  KEYSTATUS  COHERENT
    awa       -         available  yes
    owo/vtnc  -         available  yes
    owo/v nc  -         available  yes
    owo/enc   TPM1.X    available  yes


#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;

A man/zfs-tpm1x-change-key.8.pp => man/zfs-tpm1x-change-key.8.pp +107 -0
@@ 0,0 1,107 @@
.Dd
.Dt ZFS-TPM1X-CHANGE-KEY 8
.Os
.
.Sh NAME
.Nm zfs-tpm1x-change-key
.Nd change ZFS dataset key to one stored on the TPM
.Sh SYNOPSIS
.Nm
.Op Fl b Ar backup-file
.Ar dataset
.
.Sh DESCRIPTION
To normalise the
.Ar dataset ,
.Nm
will open its encryption root in its stead.
.Nm
will
.Em never
create or destroy encryption roots; use
.Xr zfs-change-key 8
for that.
.Pp
First, a connection is made to the TPM, which
.Em must
be TPM-1.X-compatible.
.Pp
If
.Ar dataset
was previously encrypted with
.Nm tzpfms
and the
.Sy TPM1.X
back-end was used, the metadata will be silently cleared.
Otherwise, or in case of an error, data required for manual intervention will be printed to the standard error stream.
.Pp
Next, a new wrapping key is be generated on the TPM, optionally backed up
.Pq see Sx OPTIONS ,
and sealed on the TPM;
the user is prompted for an optional passphrase to protect the key with,
and for the SRK passphrase, set when taking ownership, if it is not "well-known" (all zeroes).
.Pp
The following properties are set on
.Ar dataset :
.Bl -bullet -compact -offset 4n -width ""
.\"" TODO: width?
.It
.Li xyz.nabijaczleweli:tzpfms.backend Ns = Ns Sy TPM1.X
.It
.Li xyz.nabijaczleweli:tzpfms.key Ns = Ns Ar parent-key-blob Ns Cm \&: Ns Ar sealed-object-blob
.El
.Pp
.Li tzpfms.backend
identifies this dataset for work with
.Sy TPM1.X Ns -back-ended
.Nm tzpfms
tools
.Pq namely Xr zfs-tpm1x-change-key 8 , Xr zfs-tpm1x-load-key 8 , and Xr zfs-tpm1x-clear-key 8 .
.Pp
.Li tzpfms.key
is a colon-separated pair of hexadecimal-string (i.e. "4F7730" for "Ow0") blobs;
the first one represents the RSA key protecting the blob,
and it is protected with either the password, if provided, or the SHA1 constant
.Li CE4CF677875B5EB8993591D5A9AF1ED24A3A8736 ;
the second represents the sealed object containing the wrapping key,
and is protected with the SHA1 constant
.Li B9EE715DBE4B243FAA81EA04306E063710383E35 .
There exists no other user-land tool for decrypting this; perhaps there should be.
.\"" TODO: make an LD_PRELOADable for extracting the key maybe?
.Pp
Finally, the equivalent of
.Nm zfs Cm change-key Fl o Li keylocation=prompt Fl o Li keyformat=raw Ar dataset
is performed with the new key.
If an error occurred, best effort is made to clean up the properties,
or to issue a note for manual intervention into the standard error stream.
.Pp
A final verification should be made by running
.Nm zfs-tpm1x-load-key Fl n Ar dataset .
If that command succeeds, all is well,
but otherwise the dataset can be manually rolled back to a password with
.Nm zfs-tpm1x-clear-key Ar dataset
.Pq or, if that fails to work, Nm zfs Cm change-key Fl o Li keyformat=passphrase Ar dataset ,
and you are hereby asked to report a bug, please.
.Pp
.Nm zfs-tpm1x-clear-key Ar dataset
can be used to clear the properties and go back to using a password.
.
.Sh OPTIONS
.Bl -tag -compact -width "-b backup-file"
.It Fl b Ar backup-file
Save a back-up of the key to
.Ar backup-file ,
which must not exist beforehand.
This back-up
.Em must
be stored securely, off-site.
In case of a catastrophic event, the key can be loaded by running
.Dl Nm zfs Cm load-key Ar dataset Li < Ar backup-file
.El
.
#include "backend-tpm1x.h"
.
#include "common.h"
.
.Sh SEE ALSO
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm1x-change-key.md.pp => man/zfs-tpm1x-change-key.md.pp +0 -62
@@ 1,62 0,0 @@
zfs-tpm1x-change-key(8) -- change ZFS dataset key to one stored on the TPM
==========================================================================

## SYNOPSIS

`zfs-tpm1x-change-key` [-b file] <dataset>

## DESCRIPTION

To normalise `dataset`, zfs-tpm1x-change-key(8) will open its encryption root in its stead.
zfs-tpm1x-change-key(8) will *never* create or destroy encryption roots; use **zfs(8) change-key** for that.

First, a connection is made to the TPM, which *must* be TPM-1.X-compatible.

If `dataset` was previously encrypted with tzpfms and the *TPM1.X* back-end was used, the metadata will be silently cleared.
Otherwise, or in case of an error, data required for manual intervention will be printed to the standard error stream.

Next, a new wrapping key is be generated on the TPM, optionally backed up (see [OPTIONS][]),
and sealed on the TPM;
the user is prompted for an optional passphrase to protect the key with,
and for the SRK passphrase, set when taking ownership, if it is not "well-known" (all zeroes).

The following properties are set on `dataset`:

  * `xyz.nabijaczleweli:tzpfms.backend`=`TPM1.X`
  * `xyz.nabijaczleweli:tzpfms.key`=*(parent key blob)*`:`*(sealed object blob)*

`tzpfms.backend` identifies this dataset for work with *TPM1.X*-back-ended tzpfms tools
(namely zfs-tpm1x-change-key(8), zfs-tpm1x-load-key(8), and zfs-tpm1x-clear-key(8)).

`tzpfms.key` is a colon-separated pair of hexadecimal-string (i.e. "4F7730" for "Ow0") blobs;
the first one represents the RSA key protecting the blob,
and it is protected with either the password, if provided, or the SHA1 constant *CE4CF677875B5EB8993591D5A9AF1ED24A3A8736*;
the second represents the sealed object containing the wrapping key,
and is protected with the SHA1 constant *B9EE715DBE4B243FAA81EA04306E063710383E35*.
There exists no other user-land tool for decrypting this; perhaps there should be.
#comment (TODO: make an LD_PRELOADable for extracting the key maybe)

Finally, the equivalent of **zfs(8) change-key -o keylocation=prompt -o keyformat=raw dataset** is performed with the new key.
If an error occurred, best effort is made to clean up the properties,
or to issue a note for manual intervention into the standard error stream.

A final verification should be made by running **zfs-tpm1x-load-key(8) -n dataset**.
If that command succeeds, all is well,
but otherwise the dataset can be manually rolled back to a password with **zfs-tpm1x-clear-key(8) dataset** (or, if that fails to work, **zfs(8) change-key -o keyformat=passphrase dataset**), and you are hereby asked to report a bug, please.

**zfs-tpm1x-clear-key(8) dataset** can be used to clear the properties and go back to using a password.

## OPTIONS

  * `-b` *file*:
    Save a back-up of the key to *file*, which must not exist beforehand.
    This back-up **must** be stored securely, off-site.
    In case of a catastrophic event, the key can be loaded by running **zfs(8) load-key dataset < backup-file**.

#include "backend-tpm1x.h"

#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;

A man/zfs-tpm1x-clear-key.8.pp => man/zfs-tpm1x-clear-key.8.pp +39 -0
@@ 0,0 1,39 @@
.Dd
.Dt ZFS-TPM1X-CLEAR-KEY 8
.Os
.
.Sh NAME
.Nm zfs-tpm1x-clear-key
.Nd rewrap ZFS dataset key in passsword and clear tzpfms TPM1.X metadata
.Sh SYNOPSIS
.Nm
.Ar dataset
.
.Sh DESCRIPTION
After verifying
.Ar dataset
was encrypted with
.Nm tzpfms
backend
.Sy TPM1.X :
.Bl -enum -compact -offset 4n -width ""
.It
performs the equivalent of
.Nm zfs Cm change-key Fl o Li keylocation=prompt Fl o Li keyformat=passphrase Ar dataset ,
.It
removes the
.Li xyz.nabijaczleweli:tzpfms.\& Ns Brq Li backend , key
properties from
.Ar dataset .
.El
.Pp
See
.Xr zfs-tpm1x-change-key 8
for a detailed description.
.
#include "backend-tpm1x.h"
.
#include "common.h"
.
.Sh SEE ALSO
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm1x-clear-key.md.pp => man/zfs-tpm1x-clear-key.md.pp +0 -23
@@ 1,23 0,0 @@
zfs-tpm1x-clear-key(8) -- rewrap ZFS dataset key in passsword and clear tzpfms TPM1.X metadata
==============================================================================================

## SYNOPSIS

`zfs-tpm1x-clear-key` <dataset>

## DESCRIPTION

zfs-tpm1x-clear-key(8), after verifying that `dataset` was encrypted with tzpfms backend *TPM1.X* will:

  1. perform the equivalent of **zfs(8) change-key -o keylocation=prompt -o keyformat=passphrase dataset**,
  2. remove the `xyz.nabijaczleweli:tzpfms.{backend,key}` properties from `dataset`.

See zfs-tpm1x-change-key(8) for a detailed description.

#include "backend-tpm1x.h"

#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;

A man/zfs-tpm1x-load-key.8.pp => man/zfs-tpm1x-load-key.8.pp +45 -0
@@ 0,0 1,45 @@
.Dd
.Dt ZFS-TPM1X-LOAD-KEY 8
.Os
.
.Sh NAME
.Nm zfs-tpm1x-load-key
.Nd load tzpfms TPM1.X-encrypted ZFS dataset key
.Sh SYNOPSIS
.Nm
.Op Fl n
.Ar dataset
.
.Sh DESCRIPTION
After verifying
.Ar dataset
was encrypted with
.Nm tzpfms
backend
.Sy TPM1.X
will unseal the key and load it into
.Ar dataset .
.Pp
The user is prompted for, first, the SRK passphrase, set when taking ownership, if it's not "well-known" (all zeroes),
then the additional passphrase set when creating the key, if it was provided.
.Pp
See
.Xr zfs-tpm1x-change-key 8
for a detailed description.
.
.Sh OPTIONS
.Bl -tag -compact -width "-n"
.It Fl n
Do a no-op/dry run, can be used even if the key is already loaded.
Equivalent to
.Nm zfs Cm load-key Ns 's
.Fl n
option.
.El
.
#include "backend-tpm1x.h"
.
#include "common.h"
.
.Sh SEE ALSO
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm1x-load-key.md.pp => man/zfs-tpm1x-load-key.md.pp +0 -28
@@ 1,28 0,0 @@
zfs-tpm1x-load-key(8) -- load tzpfms TPM1.X-encrypted ZFS dataset key
=====================================================================

## SYNOPSIS

`zfs-tpm1x-load-key` [-n] <dataset>

## DESCRIPTION

zfs-tpm1x-load-key(8), after verifying that `dataset` was encrypted with tzpfms backend *TPM1.X* will unseal the key and load it into `dataset`.

The user is prompted for, first, the SRK passphrase, set when taking ownership, if it's not "well-known" (all zeroes),
then the additional passphrase set when creating the key, if it was provided.

See zfs-tpm1x-change-key(8) for a detailed description.

## OPTIONS

  * `-n`:
    Do a no-op/dry run, can be used even if the key is already loaded. Equivalent to **zfs(8) load-key**'s `-n` option.

#include "backend-tpm1x.h"

#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;

A man/zfs-tpm2-change-key.8.pp => man/zfs-tpm2-change-key.8.pp +104 -0
@@ 0,0 1,104 @@
.Dd
.Dt ZFS-TPM2-CHANGE-KEY 8
.Os
.
.Sh NAME
.Nm zfs-tpm2-change-key
.Nd change ZFS dataset key to one stored on the TPM
.Sh SYNOPSIS
.Nm
.Op Fl b Ar backup-file
.Ar dataset
.
.Sh DESCRIPTION
To normalise
.Ar dataset ,
.Nm
will open its encryption root in its stead.
.Nm
will
.Em never
create or destroy encryption roots; use
.Xr zfs-change-key 8
for that.
.Pp
First, a connection is made to the TPM, which
.Em must
be TPM-2.0-compatible.
.Pp
If
.Ar dataset
was previously encrypted with tzpfms and the
.Sy TPM2
back-end was used, the previous key will be freed from the TPM.
Otherwise, or in case of an error, data required for manual intervention will be printed to the standard error stream.
.Pp
Next, a new wrapping key is be generated on the TPM, optionally backed up
.Pq see Sx OPTIONS ,
and sealed to a persistent object on the TPM under the owner hierarchy;
if there is a passphrase set on the owner hierarchy, the user is prompted for it;
the user is always prompted for an optional passphrase to protect the sealed object with.
.Pp
The following properties are set on
.Ar dataset :
.Bl -bullet -compact -offset 4n -width ""
.\"" TODO: width?
.It
.Li xyz.nabijaczleweli:tzpfms.backend Ns = Ns Sy TPM2
.It
.Li xyz.nabijaczleweli:tzpfms.key Ns = Ns Ar ID of persistent object
.El
.Pp
.Li tzpfms.backend
identifies this dataset for work with
.Sy TPM2 Ns -back-ended
.Nm tzpfms
tools
.Pq namely Xr zfs-tpm2-change-key 8 , Xr zfs-tpm2-load-key 8 , and Xr zfs-tpm2-clear-key 8 .
.Pp
.Li tzpfms.key
is an integer representing the sealed object;
if needed, it can be passed to
.Nm tpm2_unseal Fl c Ev ${tzpfms.key} Op Fl p Ev ${password}
or equivalent for back-up
.Pq see Sx OPTIONS .
If you have a sealed key you can access with that or equivalent tool and set both of these properties, it will funxion seamlessly.
.Pp
Finally, the equivalent of
.Nm zfs Cm change-key Fl o Li keylocation=prompt Fl o Li keyformat=raw Ar dataset
is performed with the new key.
If an error occurred, best effort is made to clean up the persistent object and properties,
or to issue a note for manual intervention into the standard error stream.
.Pp
A final verification should be made by running
.Nm zfs-tpm2-load-key Fl n Ar dataset .
If that command succeeds, all is well,
but otherwise the dataset can be manually rolled back to a password with
.Nm zfs-tpm2-clear-key Ar dataset
.Pq or, if that fails to work, Nm zfs Cm change-key Fl o Li keyformat=passphrase Ar dataset ,
and you are hereby asked to report a bug, please.
.Pp
.Nm zfs-tpm2-clear-key Ar dataset
can be used to free the TPM persistent object and go back to using a password.
.
.Sh OPTIONS
.Bl -tag -compact -width "-b backup-file"
.It Fl b Ar backup-file
Save a back-up of the key to
.Ar backup-file ,
which must not exist beforehand.
This back-up
.Em must
be stored securely, off-site.
In case of a catastrophic event, the key can be loaded by running
.Dl Nm zfs Cm load-key Ar dataset Li < Ar backup-file
.El
.
#include "backend-tpm2.h"
.
#include "common.h"
.
.Sh SEE ALSO
.Xr tpm2_unseal 1
.Pp
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm2-change-key.md.pp => man/zfs-tpm2-change-key.md.pp +0 -58
@@ 1,58 0,0 @@
zfs-tpm2-change-key(8) -- change ZFS dataset key to one stored on the TPM
=========================================================================

## SYNOPSIS

`zfs-tpm2-change-key` [-b file] <dataset>

## DESCRIPTION

To normalise `dataset`, zfs-tpm2-change-key(8) will open its encryption root in its stead.
zfs-tpm2-change-key(8) will *never* create or destroy encryption roots; use **zfs(8) change-key** for that.

First, a connection is made to the TPM, which *must* be TPM-2.0-compatible.

If `dataset` was previously encrypted with tzpfms and the *TPM2* back-end was used, the previous key will be freed from the TPM.
Otherwise, or in case of an error, data required for manual intervention will be printed to the standard error stream.

Next, a new wrapping key is be generated on the TPM, optionally backed up (see [OPTIONS][]),
and sealed to a persistent object on the TPM under the owner hierarchy;
if there is a passphrase set on the owner hierarchy, the user is prompted for it;
the user is always prompted for an optional passphrase to protect the sealed object with.

The following properties are set on `dataset`:

  * `xyz.nabijaczleweli:tzpfms.backend`=`TPM2`
  * `xyz.nabijaczleweli:tzpfms.key`=*(ID of persistent object)*

`tzpfms.backend` identifies this dataset for work with *TPM2*-back-ended tzpfms tools
(namely zfs-tpm2-change-key(8), zfs-tpm2-load-key(8), and zfs-tpm2-clear-key(8)).

`tzpfms.key` is an integer representing the sealed object;
if needed, it can be passed to **tpm2_unseal(1) -c ${tzpfms.key} [-p ${password}]** or equivalent for back-up (see [OPTIONS][]).
If you have a sealed key you can access with that or equivalent tool and set both of these properties, it will funxion seamlessly.

Finally, the equivalent of **zfs(8) change-key -o keylocation=prompt -o keyformat=raw dataset** is performed with the new key.
If an error occurred, best effort is made to clean up the persistent object and properties,
or to issue a note for manual intervention into the standard error stream.

A final verification should be made by running **zfs-tpm2-load-key(8) -n dataset**.
If that command succeeds, all is well,
but otherwise the dataset can be manually rolled back to a password with **zfs-tpm2-clear-key(8) dataset** (or, if that fails to work, **zfs(8) change-key -o keyformat=passphrase dataset**), and you are hereby asked to report a bug, please.

**zfs-tpm2-clear-key(8) dataset** can be used to free the TPM persistent object and go back to using a password.

## OPTIONS

  * `-b` *file*:
    Save a back-up of the key to *file*, which must not exist beforehand.
    This back-up **must** be stored securely, off-site.
    In case of a catastrophic event, the key can be loaded by running **zfs(8) load-key dataset < backup-file**.

#include "backend-tpm2.h"

#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;

A man/zfs-tpm2-clear-key.8.pp => man/zfs-tpm2-clear-key.8.pp +42 -0
@@ 0,0 1,42 @@
.Dd
.Dt ZFS-TPM2-CLEAR-KEY 8
.Os
.
.Sh NAME
.Nm zfs-tpm2-clear-key
.Nd rewrap ZFS dataset key in passsword and clear tzpfms TPM2 metadata
.Sh SYNOPSIS
.Nm
.Ar dataset
.
.Sh DESCRIPTION
After verifying
.Ar dataset
was encrypted with
.Nm tzpfms
backend
.Sy TPM2 :
.Bl -enum -compact -offset 4n -width ""
.It
performs the equivalent of
.Nm zfs Cm change-key Fl o Li keylocation=prompt Fl o Li  keyformat=passphrase Ar dataset ,
.It
frees the sealed key previously used to encrypt
.Ar dataset ,
.It
removes the
.Li xyz.nabijaczleweli:tzpfms.\& Ns Brq Li backend , key
properties from
.Ar dataset .
.El
.Pp
See
.Xr zfs-tpm2-change-key 8
for a detailed description.
.
#include "backend-tpm2.h"
.
#include "common.h"
.
.Sh SEE ALSO
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm2-clear-key.md.pp => man/zfs-tpm2-clear-key.md.pp +0 -24
@@ 1,24 0,0 @@
zfs-tpm2-clear-key(8) -- rewrap ZFS dataset key in passsword and clear tzpfms TPM2 metadata
===========================================================================================

## SYNOPSIS

`zfs-tpm2-clear-key` <dataset>

## DESCRIPTION

zfs-tpm2-clear-key(8), after verifying that `dataset` was encrypted with tzpfms backend *TPM2* will:

  1. perform the equivalent of **zfs(8) change-key -o keylocation=prompt -o keyformat=passphrase dataset**,
  2. free the sealed key previously used to encrypt `dataset`,
  3. remove the `xyz.nabijaczleweli:tzpfms.{backend,key}` properties from `dataset`.

See zfs-tpm2-change-key(8) for a detailed description.

#include "backend-tpm2.h"

#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;

A man/zfs-tpm2-load-key.8.pp => man/zfs-tpm2-load-key.8.pp +42 -0
@@ 0,0 1,42 @@
.Dd
.Dt ZFS-TPM2-LOAD-KEY 8
.Os
.
.Sh NAME
.Nm zfs-tpm2-load-key
.Nd load tzpfms TPM2-encrypted ZFS dataset key
.Sh SYNOPSIS
.Nm
.Op Fl n
.Ar dataset
.
.Sh DESCRIPTION
After verifying
.Ar dataset
was encrypted with
.Nm tzpfms
backend
.Sy TPM2 ,
unseals the key and loads it into
.Ar dataset .
.Pp
See
.Xr zfs-tpm2-change-key 8
for a detailed description.
.
.Sh OPTIONS
.Bl -tag -compact -width "-n"
.It Fl n
Do a no-op/dry run, can be used even if the key is already loaded.
Equivalent to
.Nm zfs Cm load-key Ns 's
.Fl n
option.
.El
.
#include "backend-tpm1x.h"
.
#include "common.h"
.
.Sh SEE ALSO
.Lk https:/\&/git.sr.ht/~nabijaczleweli/tzpfms

D man/zfs-tpm2-load-key.md.pp => man/zfs-tpm2-load-key.md.pp +0 -25
@@ 1,25 0,0 @@
zfs-tpm2-load-key(8) -- load tzpfms TPM2-encrypted ZFS dataset key
==================================================================

## SYNOPSIS

`zfs-tpm2-load-key` [-n] <dataset>

## DESCRIPTION

zfs-tpm2-load-key(8), after verifying that `dataset` was encrypted with tzpfms backend *TPM2* will unseal the key and load it into `dataset`.

See zfs-tpm2-change-key(8) for a detailed description.

## OPTIONS

  * `-n`:
    Do a no-op/dry run, can be used even if the key is already loaded. Equivalent to **zfs(8) load-key**'s `-n` option.

#include "backend-tpm2.h"

#include "common.h"

## SEE ALSO

&lt;<https://git.sr.ht/~nabijaczleweli/tzpfms>&gt;