From 7e36691edaeeb6e007502e93956412b8efdbfffa Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 31 Jul 2025 18:01:54 +0200 Subject: [PATCH 1/6] README.md: update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e50d457..6d8f7c0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# docs +# Ampel Documentation -Documentation of the projects of Ampel. \ No newline at end of file +This is repository containing the [mkdocs](https://www.mkdocs.org) files for the [documentation](https://docs.ampel.dev) of the projects of the Ampel organisation. From 9565a038b6a1560a247ea496ebf809882cb17fdf Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 31 Jul 2025 18:02:13 +0200 Subject: [PATCH 2/6] mkdocs.yml: add --- mkdocs.yml | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 mkdocs.yml diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..9adeb4d --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,69 @@ +site_name: Ampel Documentation +site_url: https://docs.ampel.dev +copyright: This work is dedicated to the public domain under the Creative Commons CC0 public domain dedication. + + +repo_name: ampel/docs +repo_url: https://git.ampel.dev/ampel/docs + +extra: + generator: false + +theme: + name: material + features: + - navigation.instant + - navigation.instant.progress + - navigation.indexes + - navigation.tabs + - navigation.sections + - toc.follow + - search.suggest + - search.highlight + - search.share + - content.tabs.link + - content.code.copy + - content.code.annotate +# logo: assets/ampel-logo.png +# favicon: assets/ampel-logo.png + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: white + accent: blue + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: black + accent: teal + toggle: + icon: material/brightness-3 + name: Switch to light mode + +markdown_extensions: + - admonition + - attr_list + - md_in_html + - pymdownx.details + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + +plugins: + - search + - tags + +nav: + - 'Home': index.md + - 'Zlevis': + - zlevis/index.md + - 'Functionality': zlevis/functionality.md + - 'Implementation': zlevis/implementation.md From ca36c507716e08bc1c80dc01306f3b6094afd499 Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 31 Jul 2025 18:02:35 +0200 Subject: [PATCH 3/6] docs/index.md: add --- docs/index.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docs/index.md diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..1c9f683 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,9 @@ +--- +hide: + - navigation + - toc +--- + +# Welcome to the documentation of the projects of the Ampel organisation + +Here you can find all the documentation related to the projects hosted by the [Ampel](https://git.ampel.dev/ampel) organisation. \ No newline at end of file From 208c5d469ffab5e6019e27df3c8133c042088eaa Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 31 Jul 2025 18:02:51 +0200 Subject: [PATCH 4/6] docs/zlevis/index.md: add --- docs/zlevis/index.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/zlevis/index.md diff --git a/docs/zlevis/index.md b/docs/zlevis/index.md new file mode 100644 index 0000000..e214e6e --- /dev/null +++ b/docs/zlevis/index.md @@ -0,0 +1,5 @@ +# Zlevis + +[Zlevis](https://git.ampel.dev/ampel/zlevis) is a tool that enables the automatic decryption of a [ZFS](https://openzfs.org/wiki/Main_Page) root pool with [TPM 2.0](https://en.wikipedia.org/wiki/Trusted_Platform_Module#TPM_2.0). It is based on the `pin-tpm2` feature of [Clevis](https://github.com/latchset/clevis) and is rewritten in POSIX shell to omit the presence of `bash` in the `initramfs`. Just like Clevis' `pin-tmp2` feature, `zlevis` also depends on [jose](https://github.com/latchset/jose); to format configuration and generate or encrypt/decrypt keys, and on [tpm2-tools](https://github.com/tpm2-software/tpm2-tools); to read and create objects in the TPM. + +Zlevis is thus a minimal fork of Clevis, solely optimised for the automatic decryption of a ZFS root pool with TPM 2.0. \ No newline at end of file From 553b224e06bdf4bcb9fc42569ff394fcba9d92cf Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 31 Jul 2025 18:03:06 +0200 Subject: [PATCH 5/6] docs/zlevis/functionality.md: add --- docs/zlevis/functionality.md | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 docs/zlevis/functionality.md diff --git a/docs/zlevis/functionality.md b/docs/zlevis/functionality.md new file mode 100644 index 0000000..d59575c --- /dev/null +++ b/docs/zlevis/functionality.md @@ -0,0 +1,81 @@ +A cornerstone in the development of `zlevis` is simplicity, the `zlevis` package contains essentially only 2 commands and can be used with or without a ZFS root pool. + +## Usage with ZFS root pool + +When we consider the decryption of a ZFS root pool with `zlevis` the first step is to write the encryption key to the TPM. Often this encryption key is created in the provisioning phase of the installation of a system, particularly when we are still in the live ISO environment. It is common practice to write the randomly generated key to `/tmp/rpool.key` on the live ISO. After creation of the pool we may write the encryption key to the TPM by: + +``` shell-session +# zlevis encrypt rpool '{"propery":"value"}' < /tmp/rpool.key +``` + +Under `"property"` we can set the `hash`, `key`, `pcr_bank`, `pcr_ids` and `pcr_digest`. See the configuration properties section for all the options. + +This command writes a JWE (JSON Web Encryption) token to the `tpm:jwe` property of the ZFS root dataset of the root pool. This JWE token can be interpreted as the public key. You can obtain the JWE by performing: + +``` shell-session +# zfs get tpm:jwe rpool/root/ +``` + +In the now installed and configured system the encryption key of the root pool can be obtained by performing: + +``` shell-session +# zlevis decrypt rpool +``` + +This command will fetch the JWE from `tpm:jwe` and use it to obtain the encryption key. + +## Usage without ZFS root pool + +We can also use `zlevis` to plainly store keys in TPM and fetch keys from TPM. This requires us to store the JWE locally in `file.jwe`, we can write a key `file.key` to TPM with: + +``` shell-session +# zlevis-encrypt '{"propery":"value"}' < file.key > file.jwe +``` + +Under `"property"` we can set the `hash`, `key`, `pcr_bank`, `pcr_ids` and `pcr_digest`. See the configuration properties section for all the options. + +You can fetch the key with the locally stored `file.jwe` by performing: + +``` shell-session +# zlevis-decrypt < file.jwe +``` + +Marking the end of the functionality outline of `zlevis`. + +## Configuration properties + +The table of configuration properties is given below. + +| Property | Possible values | Explanation | +|----------|-----------------|-------------| +| Hash | `sha1`, `sha256`, `sha384`, `sha512`, `sm3_256` | Hash algorithm used in the computation of the object name. | +| Key | `rsa`, `keyedhash` , `ecc`, `symcipher`| Algorithm type for the generated key. | +| PCR Bank | `sha1`, `sha256`, `...` | PCR algorithm bank to use for policy. | +| PCR IDs | `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`, `16`, `23` | Comma separated list of PCR used for policy. If not present, no policy is used. | +| PCR Digest | `...` | Binary PCR hashes encoded in base64. If not present, the hash values are looked up. | + +For the full list of algorithms supported by the TPM chip check the output of + +``` shell-session +# tpm2_getcap pcrs +``` + +and use the the algorithm which shows a non-empty list of PCR IDs. + +The table describing each PCR ID is given below. + +> A detailed explanation of the TPM implementation is available at [Trusted Computing Group's website](https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/). + +| PCR | TCG Description | Notes | +|:---:|-----------------|-------| +| 0 | SRTM, BIOS, host platform extensions, embedded option, ROMs and PI drivers | Stores firmware, may change if the UEFI/BIOS is updated. Acts as the root for the chain of trust. Some implementations record CPU microcode measurements here. | +| 1 | Host platform configuration | The UEFI configuration itself, such as settings. This typically contains the entire contents of the CMOS/NVRAM, minus any dynamic or security-sensitive data. | +| 2 | UEFI driver and application code | Option ROMs. | +| 3 | UEFI driver and application configuration and data | Option ROM configuration. | +| 4 | UEFI boot manager code (usually the MBR) and boot attempts | Measures manager code itself, and that a use was attempted. | +| 5 | Boot manager code configuration and data (for use by the boot-manager code) and GPT/partition table | Measures the configuration of the boot device, including the GPT partition table of the device. | +| 6 | Host platform manufacturer specific | May be used for S4 and S5 Power State Events. | +| 7 | Secure-boot policy | Measures contents of secure-boot keys and certificates used to verify boot applications. | +| 8-15 | Defined for use by the static OS | See the documentation of the OS for more details. | +| 16 | Debug | Optional, and sometimes unused PCR. | +| 23 | Application support | Can be set and reset by the OS. | \ No newline at end of file From bc93dd73ce736be3cd2d502321006ad6437dda6e Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 31 Jul 2025 18:03:21 +0200 Subject: [PATCH 6/6] docs/zlevis/implementation.md: add --- docs/zlevis/implementation.md | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/zlevis/implementation.md diff --git a/docs/zlevis/implementation.md b/docs/zlevis/implementation.md new file mode 100644 index 0000000..e83a2a4 --- /dev/null +++ b/docs/zlevis/implementation.md @@ -0,0 +1,53 @@ +## Mkinitfs + +[Mkinitfs](https://gitlab.alpinelinux.org/alpine/mkinitfs) is the `initramfs` generator of [Alpine Linux](https://alpinelinux.org/). Among the usual operations to setup `zlevis`, i.e. writing the encryption key of the ZFS root pool to the TPM after the creation of the ZFS root pool, enabling the `zlevis-hook` in `mkinitfs.conf` and installing `zlevis` on the host system, we require to make an adaptation to the `initramfs-init` script of `mkinitfs`. + +Particularly, in the `prepare_zfs_root()` function we need to add the option `zlevis decrypt "$_root_pool" | zfs load-key -L prompt "$_root_pool"`: + + +``` shell title="/usr/share/mkinitfs/initramfs-init" hl_lines="19" linenums="385" +# Do some tasks to make sure mounting the ZFS pool is A-OK +prepare_zfs_root() { + local _root_vol=${KOPT_root#ZFS=} + local _root_pool=${_root_vol%%/*} + + # Force import if this has been imported on a different system previously. + # Import normally otherwise + if [ "$KOPT_zfs_force" = 1 ]; then + zpool import -N -d /dev -f $_root_pool + else + zpool import -N -d /dev $_root_pool + fi + + + # Ask for encryption password + if [ $(zpool list -H -o feature@encryption $_root_pool) = "active" ]; then + local _encryption_root=$(zfs get -H -o value encryptionroot $_root_vol) + if [ "$_encryption_root" != "-" ]; then + zlevis decrypt "$_root_pool" | zfs load-key -L prompt "$_root_pool" || eval zfs load-key $_encryption_root + fi + fi +} +``` + +Retaining the fallback to `eval zfs load-key` with the `||` operator. + +Furthermore, we need to configure the `zlevis-hook` by notifying `mkinitfs` which binaries and libraries to add into the `initramfs`: + +``` shell title="/etc/mkinitfs/features.d/zlevis.files" +/usr/bin/zlevis +/usr/bin/zlevis-decrypt +/usr/bin/tpm2* +/usr/bin/jose +/usr/lib/libtss2-tcti* +``` + +and to notify what kernel drivers are required: + +``` shell title="/etc/mkinitfs/features.d/zlevis.modules" +kernel/drivers/char/tpm* +``` + +## Dracut + +Work in progress. \ No newline at end of file