From 94da5270c7d916541c33ac3ea6c6d00e74b65245 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sat, 9 Dec 2023 13:52:20 -0500 Subject: [PATCH] initial --- LICENSE | 10 ++++ Makefile | 9 +++ README.md | 38 ++++++++++++ gentpm.sh | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++ tpm2_hook | 67 +++++++++++++++++++++ tpm2_install | 31 ++++++++++ 6 files changed, 320 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100755 gentpm.sh create mode 100755 tpm2_hook create mode 100755 tpm2_install diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b915b7b --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ + The MIT License (MIT) + +Copyright © 2023 Freya Murphy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e146c86 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +.PHONY: install + +install: + sudo cp tpm2_hook /etc/initcpio/hooks/tpm2 + sudo cp tpm2_install /etc/initcpio/install/tpm2 + +build: + sudo -E ./gentpm.sh all + sudo -E mkinitcpio -P diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a0e473 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +## Luks TPM + +Loads a LUKS tpm2 key during inital ramdisk to auto decrypt drive under secure conditions + +### Requirements + +#### mkinitcpio + +This setup contains hooks to be used with `mkinitcpio` + +To setup the hook run `make install` as root and then add the `tpm2` hook before the `encrypt` hook in `/etc/mkinitcpio.conf` + +#### tpm2-tools + +Make sure the `tpm2-tools` are installed so keys can be generated and unsealed + +For arch linux, its as easy as `pacman -S tpm2-tools` + +### Generating Keys + +#### Bash variables + +Before you can run the script make sure the `device`, `slot`, `keyloc`, and `pcr`, variables at the top of the script. + +- `device` - The block device the LUKS partition is located at +- `slot` - The key slot that the key will be put in (WARNING this slot will be overwritten if it contains data) +- `keyloc` - The tpm location the key will be sealed in (default is fine usually) +- `pcr` - The pcr rules for storing the key (default is fine usually) + +#### Generation + +Key generation is automatic with the `gentpm.sh` script + +Run `make build` as root, this will generate and store the keys, and also rebuild the ramdisk + +### License + +This project is licensed under the MIT license diff --git a/gentpm.sh b/gentpm.sh new file mode 100755 index 0000000..5e2bf1b --- /dev/null +++ b/gentpm.sh @@ -0,0 +1,165 @@ +#!/usr/bin/env bash + +device="/dev/nvme0n1p2" +slot="0" +keyloc="0x81000001" +pcr="sha256:7" + +ctx="" +rsapub="" +rsapriv="" +rsaname="" +rsactx="" +sealpub="" +sealpriv="" +sealname="" +sealctx="" +key="" +policy="" +authpolicy="" +sig="" +verif="" +session="" +out="" + +_STEP() { + printf '\x1b[34;1m>> %s\x1b[0m\n' "$*" 1>&2 +} + +_RUN() { + printf '$ \x1b[32;1m%s\x1b[0m\n' "$*" 1>&2 + "$@" +} + +loadvars() { + _STEP "reloading file locations" + + ctx="$out/prim.ctx" + + rsapub="$out/rsa.pub" + rsapriv="$out/rsa.priv" + rsaname="$out/rsa.name" + rsactx="$out/rsa.ctx" + + sealpub="$out/seal.pub" + sealpriv="$out/seal.priv" + sealname="$out/seal.name" + sealctx="$out/seal.ctx" + + key="$out/tpm.key" + + policy="$out/pcr.pol" + authpolicy="$out/auth.pol" + + sig="$out/pcr.pol.sig" + verif="$out/verification.tkt" + + session="$out/session.ctx" +} + +reset() { + _STEP "resetting tpm keys" + tpm2_clear + + _STEP "creating temp store" + out=$(mktemp --directory) +} + +new_context() { + _STEP "generating new context" + _RUN tpm2_startauthsession -S $session + _RUN tpm2_policypcr -Q -S $session -l $pcr -L $policy + _RUN tpm2_flushcontext $session +} + +keygen() { + + _RUN tpm2_createprimary -Q -C o -c $ctx + + _STEP "creating encryption key" + _RUN dd if=/dev/urandom bs=1 count=32 status=none 1> $key + + _STEP "creating signing keypair" + _RUN openssl genrsa -out $rsapriv 2048 + _RUN openssl rsa -in $rsapriv -out $rsapub -pubout + + new_context + + _STEP "loading signing keypair" + _RUN tpm2_loadexternal -G rsa -C o -u $rsapub -c $rsactx -n $rsaname + + _STEP "creating signer policy" + _RUN tpm2_startauthsession -S $session + _RUN tpm2_policyauthorize -S $session -L $authpolicy -n $rsaname -i $policy + _RUN tpm2_flushcontext $session + + _STEP "creating sealing object" + _RUN tpm2_create -g sha256 -u $sealpub -r $sealpriv -i $key -C $ctx -L $authpolicy + + _STEP "loading sealing object" + _RUN tpm2_evictcontrol -C o -c $keyloc + _RUN tpm2_load -Q -C $ctx -u $sealpub -r $sealpriv -n $sealname -c $sealctx + _RUN tpm2_evictcontrol -c $sealctx $keyloc -C o + + _STEP "signing pcr policy" + _RUN openssl dgst -sha256 -sign $rsapriv -out $sig $policy +} + +verify() { + _STEP "verifying signer key" + _RUN tpm2_loadexternal -G rsa -C o -u $rsapub -c $rsactx -n $rsaname + _RUN tpm2_verifysignature -c $rsactx -g sha256 -m $policy -s $sig -t $verif -f rsassa +} + +getkey() { + _RUN tpm2_startauthsession --policy-session -S $session + _RUN tpm2_policypcr -l $pcr -S $session + _RUN tpm2_policyauthorize -S $session -i $policy -n $rsaname -t $verif + _RUN tpm2_unseal -p session:$session -c $keyloc + _RUN tpm2_flushcontext $session +} + +load() { + _STEP "storing public data in etc" + _RUN rm -fr /etc/tpm2 + _RUN mkdir -p /etc/tpm2 + + _RUN cp $policy /etc/tpm2/policy + _RUN cp $rsaname /etc/tpm2/rsaname + _RUN cp $verif /etc/tpm2/verification + + _RUN printf "%s" "$pcr" > /etc/tpm2/pcr + _RUN printf "%s" "$keyloc" > /etc/tpm2/keyloc +} + +crypt() { + _STEP "copying key to crypt luks" + password="" + read -sp "Enter luks password: " password + echo + + _RUN cryptsetup luksKillSlot $device $slot < /dev/null + tpm2_policypcr -l $pcr -S $session 1> /dev/null + tpm2_policyauthorize -S $session -i $policy -n $rsaname -t $verification 1> /dev/null + + local unsealout unseal + + unsealout=$(tpm2_unseal -p session:$session -c $keyloc -o "$ckeyfile" 2>&1) + unseal=$? + + tpm2_flushcontext $session 1> /dev/null + + rm -f $session + + tpmok=0 + if [ $unseal -eq 0 ]; then + tpmok=1 + elif echo "$unsealout" | grep -sqiE 'Could not load tcti'; then + err "TPM communication error" + elif echo "$unsealout" | grep -sqiE 'Error.*0x99d'; then + echo + echo "!!! TPM WARNING: PCR VALUES HAVE CHANGED !!!" + echo "This is an indication that the boot configuration has been altered since" + echo "the TPM key was generated. This is normal after kernel updates or firmware" + echo "changes, however this could also indicate a malicious change to your system." + echo + else + err "Could not unseal TPM keyfile" + fi + + if [ $tpmok -gt 0 ]; then + msg ":: LUKS key successfully decrypted by TPM" + else + rm -f "$ckeyfile" + msg ":: TPM Could not decrypt LUKS key" + fi + + rm -fr /etc/tpm2 + +} + +run_cleanuphook() { + # Securely delete key if still present + if [ -f "$ckeyfile" ]; then + dd if=/dev/urandom of="$ckeyfile" bs=$(stat --printf="%s" "$ckeyfile") count=1 conv=notrunc 2>&1 >/dev/null + rm -f "$ckeyfile" + fi +} diff --git a/tpm2_install b/tpm2_install new file mode 100755 index 0000000..5657823 --- /dev/null +++ b/tpm2_install @@ -0,0 +1,31 @@ +#!/bin/bash + +build() { + add_module "tpm_tis" + add_module "tpm_crb" + + add_binary "/usr/bin/tpm2_unseal" + add_binary "/usr/bin/tpm2_policypcr" + add_binary "/usr/bin/tpm2_policyauthorize" + add_binary "/usr/bin/tpm2_flushcontext" + add_binary "/usr/bin/tpm2_startauthsession" + add_binary "/usr/bin/tpm2_load" + + add_binary "/usr/lib/libtss2-tcti-device.so.0" + + add_file "/etc/tpm2/policy" + add_file "/etc/tpm2/rsaname" + add_file "/etc/tpm2/verification" + add_file "/etc/tpm2/pcr" + add_file "/etc/tpm2/keyloc" + + add_runscript +} + +help() { + cat <