summaryrefslogtreecommitdiff
path: root/tpm2_hook
blob: c8aa261f6b64582f2bb2bd5c951350957094a1b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/ash
# vim: set ft=sh

tpm_cleanup() {
	rm -fr /etc/tpm2
	rm -f "$session"
	rm -f "$verification"
}

tpm_error_cleanup() {
	rm -f "$ckeyfile"
	tpm_cleanup
}

quiet() {
	$@ > /dev/null
}

run_hook() {	

	local ckeyfile policy session rsaname verification keyloc pcr tpmdev session

	if [ ! -d "/etc/tpm2" ]; then
		err "TPM data directory not found: /etc/tpm2"
		tpm_cleanup
		return
	fi

	ckeyfile="/crypto_keyfile.bin"

	if [ -f $ckeyfile ]; then
		err "Crypto keyfile already exists in root. Aborting!!!"
		tpm_cleanup
		return
	fi

	policy="/etc/tpm2/policy"
	rsaname="/etc/tpm2/rsaname"
	rsapub="/etc/tpm2/rsapub"
	rsasig="/etc/tpm2/rsasig"
	rsactx="/etc/tpm2/rsactx"

	if [ ! -f $policy ] || [ ! -f $rsaname ] || [ ! -f $rsapub ] || [ ! -f $rsasig ] || [ ! -f $rsactx ]; then
		err "TPM load data missing"
		tpm_cleanup
		return
	fi

	pcr=$(cat /etc/tpm2/pcr)
	keyloc=$(cat /etc/tpm2/keyloc)

	session="/session.ctx"
	verification="/verification.tkt"

	quiet tpm2_loadexternal -G rsa -C o -u $rsapub -c $rsactx -n $rsaname
	quiet tpm2_verifysignature -c $rsactx -g sha256 -m $policy -s $rsasig -t $verification -f rsassa

	if [ $? -eq 1 ]; then
		echo
		echo "!!! TPM WARNING: COULD NOT VERIFY SIGNATURE !!!"
		echo "The boot configuration has been altered since the TPM key was generated. "
		echo "This should NOT happen under normal use. Be paranoid."
		echo
		tpm_error_cleanup
		return
	fi

	quiet tpm2_startauthsession --policy-session -S $session
	quiet tpm2_policypcr -l $pcr -S $session
	quiet tpm2_policyauthorize -S $session -i $policy -n $rsaname -t $verification

	local unsealout unseal

	unsealout=$(tpm2_unseal -p session:$session -c $keyloc -o "$ckeyfile" 2>&1)
	unseal=$?

	quiet tpm2_flushcontext $session

	if [ $unseal -gt 0 ]; then
		if 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
		tpm_error_cleanup
	else
		msg ":: LUKS key successfully decrypted by TPM"
		tpm_cleanup
	fi

}

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
}