diff --git a/src/zlevis-decrypt b/src/zlevis-decrypt deleted file mode 100644 index 1d6ee03..0000000 --- a/src/zlevis-decrypt +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh - -# Exit immediately if a command exits with a non-zero status -set -e - -# Summary of the script's functionality -summary="Decrypts a JWE using a TPM2.0 chip." - -# TPM2.0 owner hierarchy to be used by the Operating System -auth="o" - -# Display summary if requested -if [ "$1" = "--summary" ]; then - echo "$summary" - exit 0 -fi - -# Display usage information if input is from a terminal -if [ -t 0 ]; then - exec >&2 - echo - echo "Usage: \"zlevis-decrypt < file.jwe\"" - echo "Usage ZFS: \"zfs list -Ho tpm:jwe | zlevis-decrypt\"" - echo - echo "$summary" - exit 2 -fi - -# Function to clean up temporary files on exit -on_exit() { - if [ ! -d "$tmp" ] || ! rm -rf "$tmp"; then - echo "Delete temporary files failed" >&2 - echo "You need to clean up: $tmp" >&2 - exit 1 - fi -} - -# Get the version of tpm2-tools -tpm2tools_version=$(tpm2_createprimary -v | awk -F'version="' '{print $2}' | awk -F'.' '{print $1}') - -# Check if the tpm2-tools version is supported -if [ -z "$tpm2tools_version" ] || [ "$tpm2tools_version" -lt 4 ] || [ "$tpm2tools_version" -gt 5 ]; then - echo "The tpm2 pin requires a tpm2-tools version between 4 and 5" - exit 1 -fi - -# Create a temporary directory for TPM files -if ! tmp="$(mktemp -d)"; then - echo "Creating a temporary dir for TPM files failed" >&2 - exit 1 -fi - -# Set up cleanup on exit -trap 'on_exit' EXIT - -# Read the JWE protected header -read -r -d . hdr - -# Decode the JWE protected header -if ! jhd="$(jose b64 dec -i- < <(echo "$hdr"))"; then - echo "Error decoding JWE protected header" >&2 - exit 1 -fi -echo "$jhd" > "$tmp"/jhd - -# Validate the JWE pin type -if [ "$(jose fmt -j- -Og clevis -g pin -u- < "$tmp"/jhd)" != "tpm2" ]; then - echo "JWE pin mismatch" >&2 - exit 1 -fi - -# Extract required parameters from the JWE header -if ! hash="$(jose fmt -j- -Og clevis -g tpm2 -g hash -Su- < "$tmp"/jhd)"; then - echo "JWE missing required 'hash' header parameter!" >&2 - exit 1 -fi -if ! key="$(jose fmt -j- -Og clevis -g tpm2 -g key -Su- < "$tmp"/jhd)"; then - echo "JWE missing required 'key' header parameter!" >&2 - exit 1 -fi -if ! jwk_pub="$(jose fmt -j- -Og clevis -g tpm2 -g jwk_pub -Su- < "$tmp"/jhd)"; then - echo "JWE missing required 'jwk_pub' header parameter!" >&2 - exit 1 -fi -echo "$jwk_pub" > "$tmp"/jwk_pub -if ! jwk_priv="$(jose fmt -j- -Og clevis -g tpm2 -g jwk_priv -Su- < "$tmp"/jhd)"; then - echo "JWE missing required 'jwk_priv' header parameter!" >&2 - exit 1 -fi -echo "$jwk_priv" > "$tmp"/jwk_priv - -# Handle optional PCR parameters -pcr_ids="$(jose fmt -j- -Og clevis -g tpm2 -g pcr_ids -Su- < "$tmp"/jhd)" || true -pcr_spec="" -if [ -n "$pcr_ids" ]; then - pcr_bank="$(jose fmt -j- -Og clevis -g tpm2 -g pcr_bank -Su- < "$tmp"/jhd)" - pcr_spec="$pcr_bank:$pcr_ids" -fi - -# Decode the public and private keys from Base64 -if ! jose b64 dec -i- -O "$tmp"/jwk.pub < "$tmp"/jwk_pub; then - echo "Decoding jwk.pub from Base64 failed" >&2 - exit 1 -fi -if ! jose b64 dec -i- -O "$tmp"/jwk.priv < "$tmp"/jwk_priv; then - echo "Decoding jwk.priv from Base64 failed" >&2 - exit 1 -fi - -# Create the primary key in the TPM -case "$tpm2tools_version" in - 4|5) tpm2_createprimary -Q -C "$auth" -g "$hash" -G "$key" -c "$tmp"/primary.context || fail=$?;; - *) fail=1;; -esac -if [ -n "$fail" ]; then - echo "Creating TPM2 primary key failed" >&2 - exit 1 -fi -tpm2_flushcontext -t - -# Load the JWK into the TPM -case "$tpm2tools_version" in - 4|5) tpm2_load -Q -C "$tmp"/primary.context -u "$tmp"/jwk.pub -r "$tmp"/jwk.priv -c "$tmp"/load.context || fail=$?;; - *) fail=1;; -esac -if [ -n "$fail" ]; then - echo "Loading jwk to TPM2 failed" >&2 - exit 1 -fi -tpm2_flushcontext -t - -# Unseal the JWK from the TPM -case "$tpm2tools_version" in - 4|5) jwk="$(tpm2_unseal -c "$tmp/load.context" ${pcr_spec:+-p pcr:$pcr_spec})" || fail=$?;; - *) fail=1;; -esac -if [ -n "$fail" ]; then - echo "Unsealing jwk from TPM failed" >&2 - exit 1 -fi -tpm2_flushcontext -t - -# Output the decrypted JWK along with the original header -(echo "$jwk$hdr."; /bin/cat) | jose jwe dec -k- -i- - -# Exit with the status of the last command -exit $? \ No newline at end of file diff --git a/src/zlevis-encrypt b/src/zlevis-encrypt index a171674..3e50ffd 100644 --- a/src/zlevis-encrypt +++ b/src/zlevis-encrypt @@ -9,6 +9,12 @@ summary="Encrypts using a TPM2.0 chip binding policy." # TPM2.0 owner hierarchy to be used by the Operating System auth="o" +# Algorithm type for the TPM2 object with user-provided sensitive data +alg_create_key="keyedhash" + +# Policy options for the TPM2 object +policy_options="" + # Attributes for the created TPM2 object with the JWK as sensitive data obj_attr="fixedtpm|fixedparent|noda|adminwithpolicy" @@ -21,11 +27,7 @@ fi # Display usage information if input is from a terminal if [ -t 0 ]; then exec >&2 - echo - echo "Usage: \"zlevis-encrypt '{\"property\":\"value\"}' < file.key > file.jwe\"" - echo - echo "Usage ZFS: \"zfs set tpm:jwe=\$(zlevis-encrypt '{\"property\":\"value\"}' < tank.key) \"" - echo + echo "Usage: zlevis-encrypt '{\"property\":\"value\"}' < tank.key > tank.jwe" echo echo "$summary" echo @@ -51,7 +53,7 @@ validate_pcrs() { _pcrs_r="" case "${_tpm2_tools_v}" in 4|5) _pcrs_r=$(tpm2_pcrread "${_pcr_bank}":"${_pcrs}" | grep -v " ${_pcr_bank}") || _fail=$?;; - *) _fail=1;; + *) _fail=1 esac # Check for errors in PCR validation @@ -74,12 +76,13 @@ on_exit() { tpm2tools_version=$(tpm2_createprimary -v | awk -F'version="' '{print $2}' | awk -F'.' '{print $1}') # Check if the tpm2-tools version is supported -if [ -z "$tpm2tools_version" ] || [ "$tpm2tools_version" -lt 4 ] || [ "$tpm2tools_version" -gt 5 ]; then +if [ -z "$tpm2tools_version" ] || [ $tpm2tools_version -lt 4 ] || [ $tpm2tools_version -gt 5 ]; then echo "The tpm2 pin requires a tpm2-tools version between 4 and 5" exit 1 fi # Create a temporary directory for TPM files +mkdir -p "${tmpdir:-/tmp}" if ! tmp="$(mktemp -d)"; then echo "Creating a temporary dir for TPM files failed" >&2 exit 1 @@ -159,7 +162,6 @@ fi tpm2_flushcontext -t # Handle PCRs and policy creation if PCR IDs are provided -policy_options="" if [ -n "$pcr_ids" ]; then if [ -z "$pcr_digest" ]; then case "$tpm2tools_version" in diff --git a/src/zlevis-fetch b/src/zlevis-fetch deleted file mode 100644 index fa8e2b6..0000000 --- a/src/zlevis-fetch +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# Exit immediately if a command exits with a non-zero status -set -e - -# Check if zlevis-decrypt is present -command -v zlevis-decrypt > /dev/null || exit 1 - -# Read ZFS dataset information. -zfs list -Ho name,encryption,keystatus,encryptionroot,tpm:jwe | while IFS=$'\t' read -r ds enc keystatus encroot jwe; do - # Check if the dataset is the encryption root. - if [ "$ds" = "$encroot" ] && [ "$enc" != "off" ] && [ "$jwe" != "-" ]; then - if [ "$keystatus" = "available" ]; then - echo "Pool $ds already unlocked" - else - echo "Loading key for $ds" - if echo -n "$jwe" | zlevis-decrypt | zfs load-key -L prompt "$ds"; then - echo "Unlocked $ds" - else - echo "FAILED TO UNLOCK $ds" >&2 - exit 1 - fi - fi - fi -done \ No newline at end of file