Utility to convert swtpm logs to binary for use with tpmstream
Closed this issue · 3 comments
Hi, I started writing my own tpm log parser to grok the output of https://github.com/stefanberger/swtpm debug logs, but then found yours which is very elegantly written and has saved me a load of time.
I'm ignoring the control commands as I can't find them in the TCG docs, and the '0x00C1' packet. Even though tpmstream
can't parse the packet it could be skipped as the length of the packet in the header is correct, so could be skipped with a hex dump provided instead?
Unknown packet & response (first packet which occurs after command codes). When this is skipped everything else works fine:
SWTPM_IO_Read: length 10
00 C1 00 00 00 0A 00 00 00 F1
SWTPM_IO_Write: length 10
80 01 00 00 00 0A 00 00 00 84
Example swtpm
command:
swtpm socket --tpmstate dir=`pwd`/.swtpm/ \
--ctrl type=unixio,path=`pwd`/.swtpm/tpm.sock \
--log level=40,file=`pwd`/.swtpm/log \
--tpm2 -d --pid file=`pwd`/.swtpm/tpm.pid
Example log file:
Ctrl Cmd: length 4
00 00 00 10
Ctrl Rsp: length 4
00 00 00 00
SWTPM_IO_Read: length 10
80 01 00 00 00 0A 00 00 01 81
SWTPM_IO_Write: length 10
80 01 00 00 00 0A 00 00 01 01
Ctrl Cmd: length 4
00 00 00 01
Ctrl Rsp: length 8
00 00 00 00 00 00 FF FF
Ctrl Cmd: length 4
00 00 00 0E
Ctrl Rsp: length 4
00 00 00 00
Ctrl Cmd: length 8
00 00 00 11 00 00 00 00
Ctrl Rsp: length 16
00 00 00 00 00 00 10 00 00 00 0A F8 00 00 10 00
Ctrl Cmd: length 4
00 00 00 0E
Ctrl Rsp: length 4
00 00 00 00
Ctrl Cmd: length 8
00 00 00 11 00 00 10 00
Ctrl Rsp: length 16
00 00 00 00 00 00 10 00 00 00 0A F8 00 00 10 00
Ctrl Cmd: length 8
00 00 00 02 00 00 00 00
Ctrl Rsp: length 4
00 00 00 00
Ctrl Cmd: length 4
00 00 00 04
Ctrl Rsp: length 8
00 00 00 00 00 00 00 00
Ctrl Cmd: length 8
00 00 00 05 00 00 00 00
Ctrl Rsp: length 4
00 00 00 00
SWTPM_IO_Read: length 10
00 C1 00 00 00 0A 00 00 00 F1
SWTPM_IO_Write: length 10
80 01 00 00 00 0A 00 00 00 84
SWTPM_IO_Read: length 12
80 01 00 00 00 0C 00 00 01 44 00 00
SWTPM_IO_Write: length 10
80 01 00 00 00 0A 00 00 00 00
SWTPM_IO_Read: length 22
80 01 00 00 00 16 00 00 01 7A 00 00 00 05 00 00
00 00 00 00 00 01
SWTPM_IO_Write: length 43
80 01 00 00 00 2B 00 00 00 00 00 00 00 00 05 00
00 00 04 00 04 03 FF FF FF 00 0B 03 FF FF FF 00
0C 03 FF FF FF 00 0D 03 FF FF FF
The script:
#!/usr/bin/env python3
import sys
def parse_tpmlog(handle):
skip = 0
for line in handle:
cmd, args = line.strip().split(':')
args = args.strip(' ').split(' ')
is_io = cmd in ('SWTPM_IO_Read', 'SWTPM_IO_Write')
assert args[0] == 'length'
length = int(args[1])
toks = b''
for line in handle:
toks += bytes([int(_, 16) for _ in line.strip().split(' ')])
if len(toks) >= length:
break
# This seems to be specific to QEMU & swtpm, it breaks tpmstream parsing
if cmd == 'SWTPM_IO_Read' and toks[:2] == bytes([0x00, 0xc1]):
skip = 2
if is_io:
if skip > 0:
skip -= 1
else:
yield toks
def main(log_path, out_path):
with open(log_path, 'r') as in_handle:
with open(out_path, 'wb') as out_handle:
for packet in parse_tpmlog(in_handle):
out_handle.write(packet)
return 0
if __name__ == "__main__":
sys.exit(main(*sys.argv[1:]))
I'm ignoring the control commands as I can't find them in the TCG docs, and the '0x00C1' packet.
Naturally. They are not standardized, but swtpm-proprietary.
Even though tpmstream can't parse the packet it could be skipped as the length of the packet in the header is correct, so could be skipped with a hex dump provided instead?
Maybe support for these command could be added to tpmstream
. That depends mainly if the format for swtpm (and perhaps also ibmtpm/mssim) is compatible with how tpmstream works under the hood. However, that format might change and break things.
Also, a switch --input-format
is conceivable (or auto-recognizing it) where tpmstream supports "swtpm log format" alltogether. I'm cautious here, though. These types of logs are not intended to be parsed. This would break in the future, for sure.
A better option would be to add support for dumping raw TPM commands/responses in swtpm. Contrary to log files, that format is actually specified and stable. Then you could plug swtpm and tpmstream simply together using a pipe.