Conversation
tstruk
left a comment
There was a problem hiding this comment.
Nice to see that someone spent some time to work on some new debugging tools. We have this in our backlog for some time already. Thanks Johannes! In general this is great idea. I have added some questions and comments with regards to some implementation details.
configure.ac
Outdated
| [enable_tcti_pcap=yes]) | ||
| AM_CONDITIONAL([ENABLE_TCTI_PCAP], [test "x$enable_tcti_pcap" != xno]) | ||
| AS_IF([test "x$enable_tcti_pcap" = "xyes"], | ||
| AC_DEFINE([TCTI_PCAP],[1], [TCTI FOR DEBUGGING])) |
There was a problem hiding this comment.
I don't see where is the TCTI_PCAP define used
There was a problem hiding this comment.
It is not used. That's a copy-paste error, removing it.
src/tss2-tcti/tcti-pcap-builder.c
Outdated
| #define PCAP_BLOCK_TYPE_EPB 0x00000006 | ||
| #define PCAP_SHB_BYTE_ORDER_MAGIC 0x1A2B3C4D | ||
| #define PCAP_SHB_SECTION_LEN_NOT_SPECIFIED 0xFFFFFFFFFFFFFFFFUL | ||
| #define PCAP_IDB_LINKTYPE_ETHERNET 0x0001 |
There was a problem hiding this comment.
We could set the link type to LINKTYPE_IPV4 (0xE4) and skip the whole Ethernet segment creation logic. The dissector only needs TCP (port number) and TPM2 segments.
There was a problem hiding this comment.
Thank you, I overlooked that. Switching to PCAP_IDB_LINKTYPE_IPv4 (0x00E4) and removing the ethernet frame. Now we have a IP packet wrapping a TCP segment wrapping a TPM request/response.
| } else if (!strcmp (filename, "stderr")) { | ||
| ctx->fd = STDERR_FILENO; | ||
| } else { | ||
| ctx->fd = open (filename, O_WRONLY | O_APPEND | O_CREAT | O_NONBLOCK, 0644); |
There was a problem hiding this comment.
How is this append functionality gonna work?
I thought we can not just "append to file" because the original pcap header will have the same old snapshot length value and the interpreter, which will read the file won't see the new addition. I thought this new data needs to be "merged" in to the old file and the old pcap header updated, similarly to what the mergecap tool does (https://www.wireshark.org/docs/man-pages/mergecap.html)
There was a problem hiding this comment.
The file header is a Section Header Block (SHB) and an Interface Description Block (IDB). In the SHB, you can use a Section Length of -1 which means unspecified.
If the Section Length is -1
(0xFFFFFFFFFFFFFFFF), this means that the size of the section is
not specified, and the only way to skip the section is to parse
the blocks that it contains.
And generally, multiple SHBs are allowed:
However, more than
one Section Header Block can be present in the capture file, each one
covering the data following it until the next one (or the end of
file).
Same for IDBs:
An Interface Description Block is valid only inside the section to
which it belongs.
So appending should (and does) work just fine.
src/tss2-tcti/tcti-pcap-builder.c
Outdated
| return pdu_len; | ||
| } | ||
|
|
||
| static int pcap_write_ethernet_frame ( |
There was a problem hiding this comment.
If we set the PCAP link type to LINKTYPE_IPV4 this won't be needed. We can just do straight pcap_write_ip_packet()
There was a problem hiding this comment.
You're right. Removing this.
| (uintptr_t)tctiContext, (uintptr_t)size, conf); | ||
| } | ||
|
|
||
| rc = Tss2_TctiLdr_Initialize (conf, &tcti_pcap->tcti_child); |
There was a problem hiding this comment.
The user will call, for instance, tpm2_getrandom -T "pcap:device:/dev/tpm0", which will cause the tcti loader to load libtss2-tcti-pcap.so and call Init() on it, passing the configuration string "pcap:device:/dev/tpm0", which again will cause the tcti loader to load
libtss2-tcti-pcap.so and call Init() on it, passing the configuration string "pcap:device:/dev/tpm0" and so on... Don't we need to parse the config here and skip the "pcap" prefix and only call Tss2_TctiLdr_Initialize() with conf = "device:/dev/tpm0"?
There was a problem hiding this comment.
Almost. The string "pcap:device:/dev/tpm0" is name:conf, so the tcti loader will load the tcti-pcap library and pass its conf device:/dev/tpm0 to it.
The tcti-pcap calls then the tcti loader with device:/dev/tpm0 which loads tcti-device.
There was a problem hiding this comment.
Yes, you are right. Looks good
Add a TCTI module which prints TPM commands and responses to a file
"tpm2_log.pcap" in pcap-ng format. By setting the TCTI_PCAP_FILE
environment variable, the output can be redirected to another path
("stdout"/"-" and "stderr" are valid values).
To use this TCTI, just prepend the TCTI name:conf string with "pcap",
e.g. "pcap:device:/dev/tpm0"
To inspect traffic in realtime with wireshark, it can be piped directly.
Of course, in this example, the program must not output any additional
information to stdout.
e.g. TCTI_PCAP_FILE=- ./program | wireshark -ki-
Signed-off-by: Johannes Holland <joh.ho@gmx.de>
Codecov Report
@@ Coverage Diff @@
## master #1817 +/- ##
==========================================
+ Coverage 83.92% 83.97% +0.04%
==========================================
Files 337 339 +2
Lines 38987 39257 +270
==========================================
+ Hits 32720 32966 +246
- Misses 6267 6291 +24
Continue to review full report at Codecov.
|
| (uintptr_t)tctiContext, (uintptr_t)size, conf); | ||
| } | ||
|
|
||
| rc = Tss2_TctiLdr_Initialize (conf, &tcti_pcap->tcti_child); |
There was a problem hiding this comment.
Yes, you are right. Looks good
| } else if (!strcmp (filename, "stderr")) { | ||
| ctx->fd = STDERR_FILENO; | ||
| } else { | ||
| ctx->fd = open (filename, O_WRONLY | O_APPEND | O_CREAT | O_NONBLOCK, 0644); |
|
Would be good to enable some of the CI to go through pcap and see what it produces. I will play with it a bit and see what we can do. Also I wonder how the partial read captures will look in wireshark. |
|
Spoiler alert: With partial read, you will not see any difference. The first read (for the response size) is not logged. only the second complete receive call is logged (similar to what is implemented with the |
Although wireshark features a neat TPM traffic dissector, there is no way to log+parse non-simulator TPM traffic. Additionally, to my knowledge, there is no alternative TPM traffic parser for Linux.
Add a TCTI module which prints TPM traffic to a file
tpm2_log.pcapin pcap-ng format. Via the env. variableTCTI_PCAP_FILE, the output can be redirected to another path/stream (stdout,-, andstderrare valid values). Iftpm2_log.pcapalready exists, the logs are appended.To use this TCTI, just prepend the TCTI name:conf string with "pcap", e.g.
To inspect traffic in realtime with wireshark, it can be piped directly. Of course, in this example, the program must not output any additional information to
stdout.