Skip to content

Commit 89f0eea

Browse files
txt-tpm1-evt-log-parser.awk: add parser for Intel TXT TPM 1.2 event log
Contrary to TPM 2.0 format, this one is specific to Intel TXT and cannot be used for parsing firmware entries, hence the seemingly inconsistent file name. Similarly to TPM 2.0 parser, this one also must operate on regular file. Signed-off-by: Krystian Hebel <[email protected]>
1 parent 61da563 commit 89f0eea

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

anti-evil-maid.spec.in

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ cp -r systemd $RPM_BUILD_ROOT/usr/lib
5050
/usr/sbin/anti-evil-maid-seal
5151
/usr/sbin/anti-evil-maid-tpm-setup
5252
/usr/sbin/tpm2-evt-log-parser.awk
53+
/usr/sbin/txt-tpm1-evt-log-parser.awk
5354
/usr/share/doc/anti-evil-maid/README
5455
/usr/lib/systemd/system/anti-evil-maid-seal.service
5556
/usr/lib/systemd/system/tcsd.service.d/anti-evil-maid-seal.conf

sbin/anti-evil-maid-dump-evt-log

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ dd if=/dev/mem bs=1 skip=$base count=$size of=/tmp/log.bin
1616
if [ "$_tpm_version" -eq 2 ]; then
1717
/usr/sbin/tpm2-evt-log-parser.awk /tmp/log.bin
1818
else
19-
echo "TPM 1.2 event log format not supported yet"
19+
# Intel only, unless AMD implementation will choose to use TXT format
20+
/usr/sbin/txt-tpm1-evt-log-parser.awk /tmp/log.bin
2021
fi
2122

2223
rm /tmp/log.bin

sbin/txt-tpm1-evt-log-parser.awk

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/gawk -bf
2+
@load "readfile"
3+
4+
function assert(condition, string)
5+
{
6+
if (!condition) {
7+
print string
8+
exit 1
9+
}
10+
}
11+
12+
function ord_init()
13+
{
14+
for (_i = 0; _i < 256; _i++) {
15+
ord[sprintf("%c", _i)] = _i
16+
}
17+
}
18+
19+
function x2n(hex, width)
20+
{
21+
mult = 1
22+
num = 0
23+
for (_i = 0; _i < width; _i++) {
24+
num += ord[substr(hex, _i+1, 1)] * mult
25+
mult *= 256
26+
}
27+
return num
28+
}
29+
30+
function hexdump(hex, len)
31+
{
32+
for (_i = 0; _i < len; _i++) {
33+
printf("%02x", ord[substr(hex, _i+1, 1)])
34+
}
35+
}
36+
37+
function string_or_hex(str, len)
38+
{
39+
_len = len
40+
if (_len > 128)
41+
_len = 128
42+
# String must start with a series of printable characters ...
43+
if (match(str, "[[:graph:][:blank:]]*", a) != 1) {
44+
hexdump(str, _len)
45+
# ... long until the end, with "optional" (i.e. bad implementation) \0.
46+
} else if (len != a[0, "length"] &&
47+
(len != a[0, "length"] + 1 || index(str, "\0") != len)) {
48+
hexdump(str, _len)
49+
} else
50+
printf("%.*s", _len, a[0])
51+
if (_len != len)
52+
printf("... (event truncated to %d first bytes, was %d)", _len, len)
53+
}
54+
55+
BEGIN {
56+
PROCINFO["readfile"]
57+
FIELDWIDTHS = "20 12 1 1 1 1 4 4 4 *"
58+
ord_init()
59+
}
60+
{
61+
# Header sanity checks
62+
assert($1 == "TXT Event Container\0", "Bad TXT Event Container signature")
63+
assert(match($2, "\0{12}"), "Reserved field is not all 0")
64+
assert($3 == "\1", "Bad container major version")
65+
# Minor version is bumped if there are compatible changes like new
66+
# fields added to the end of structure. Header stores offset to PCR
67+
# events so those new fields can be skipped.
68+
#assert($4 == "\0", "Bad container minor version")
69+
assert($5 == "\1", "Bad event structure major version")
70+
# There is no field that would specify size of whole event structure,
71+
# any new fields added to it would break this parser.
72+
assert($6 == "\0", "Bad event structure minor version")
73+
assert(x2n($7, 4) == length(), "Bad container size")
74+
assert(x2n($8, 4) >= (20+12+1+1+1+1+4+4+4), "PCR Event offset too small")
75+
assert(x2n($9, 4) > x2n($8, 4), "Next Event offset too small")
76+
FIELDWIDTHS="4 4 20 4 *"
77+
$0 = substr($0, x2n($8, 4) + 1)
78+
}
79+
{
80+
entry = 0
81+
printf("\n")
82+
while (NF > 0) {
83+
if ($2 == "\0\0\0\0") break
84+
printf("Entry %d:\n", ++entry)
85+
printf(" PCR: %d\n", x2n($1, 4))
86+
printf(" Event Type: %#x\n", x2n($2, 4))
87+
printf(" Digests:\n")
88+
printf(" SHA1: ")
89+
hexdump($3, 20)
90+
printf("\n")
91+
printf(" Event: ")
92+
string_or_hex($5, x2n($4, 4))
93+
printf("\n\n")
94+
$0 = substr($5, x2n($4, 4) + 1)
95+
}
96+
}

0 commit comments

Comments
 (0)