tpm2-software / tpm2-pytss

Python bindings for TSS
https://tpm2-pytss.readthedocs.io/en/latest/
BSD 2-Clause "Simplified" License
62 stars 45 forks source link

Unmarshalling a complete TPM request/response #322

Open ghost opened 2 years ago

ghost commented 2 years ago

Hello,

I got a question about this library:

Suppose I have a complete hexstream of a TPM request/response (let's say a TPM2_CREATE command), how can I do to unmarshal everything at once ? I know I can umarshall some bits of this hexstream separetly, but I don't know how can I do everything at once.

Here is an example of such hex stream:

80020000007e00000153800000010000004902000000002025bb72d45e1c8254487aadf6bcf74d77f37b853ee62d68f7c5239139434909db010020f047d69dc6c4046219202a71f6863b095ce3d61de9c54f7ca01c14eda95b8f39000b000000075365637265740a000e0008000b00000052000000100000000000000000

In this hex stream I got multiple different structure, for example at the end I got a TPM2B_SENSITIVE_CREATE structure, is there a structure that is above all of them so I can umarshall in this type ?

williamcroberts commented 2 years ago

You need to unmarshal the command and then unmarshal the paramters. Their is no library support for this at the moment, but if you look at the C code in tpm2_send (tpm2-tools project), you'll see an example of breaking apart the command stream.

FYI wireshark if you use the pcap TCTI can break this apart for you, but not the parameters.

ghost commented 2 years ago

I looked inside the tpm2_send.c file, I guess you are talking about these function for example: tpm2_command_header_get_code, tpm2_command_header_get_tag, ....?

If I understand correctly, my hexstream is basically like that: TPM2_HEADER | TPM2_PARAMETERS, right ?

williamcroberts commented 2 years ago

Yeah the beginning of every TPM command has a fixed length header, then the parameters. The command spec shows the layouts of the parameters and the header IIRC: https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part3_Commands_pub.pdf

niooss-ledger commented 2 years ago

If I understand correctly, my hexstream is basically like that: TPM2_HEADER | TPM2_PARAMETERS, right ?

For information, the format of the serialized commands is documented in "Trusted Platform Module Library Family "2.0" Specification - Part 3: Commands, Revision 1.38" specification available at https://trustedcomputinggroup.org/resource/tpm-library-specification/

For example TPM2_Create command is described in table 19:

image

For your information, in this table, the seperators between commandCode and parentHandle, and between parentHandle and inSensitive have specific meanings, described in section 4.2.1. "Handle and Parameter Demarcation", and depending on how the command is invoked, its marshaled bytes could be organized differently.

ghost commented 2 years ago

That's the piece I was missing, thanks @niooss-ledger and @williamcroberts !

williamcroberts commented 2 years ago

@fer9898 i'd take a method for this in the python code where you give it a hex stream and returns all the pieces.

ghost commented 2 years ago

Yeah it would be great, but I don't know if I can do this, as @niooss-ledger said

depending on how the command is invoked, its marshaled bytes could be organized differently.

I didn't looked it up yet, but I guess there is a lot of cases to cover

williamcroberts commented 2 years ago

The header is common, and then the per-command data structures. But something like a command code to 'deserializing' map could be made. Just getting the framework started and then folks could help you populate that decoder map for all commands.