{"id":16646049,"url":"https://github.com/joholl/tpmstream","last_synced_at":"2025-04-09T16:06:56.145Z","repository":{"id":37416091,"uuid":"477460073","full_name":"joholl/tpmstream","owner":"joholl","description":"A tool to help you understand TPM commands and responses.","archived":false,"fork":false,"pushed_at":"2024-12-03T09:26:08.000Z","size":947,"stargazers_count":41,"open_issues_count":4,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T16:06:54.090Z","etag":null,"topics":["tpm","tpm2"],"latest_commit_sha":null,"homepage":"https://joholl.github.io/tpmstream-web","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joholl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-03T20:39:10.000Z","updated_at":"2025-03-14T15:19:35.000Z","dependencies_parsed_at":"2024-01-29T14:52:40.107Z","dependency_job_id":"9ca73c87-a6f3-4882-8522-48a217828488","html_url":"https://github.com/joholl/tpmstream","commit_stats":{"total_commits":83,"total_committers":4,"mean_commits":20.75,"dds":"0.10843373493975905","last_synced_commit":"15f42a112da243892a8a49fa0603f98a6112ac16"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joholl%2Ftpmstream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joholl%2Ftpmstream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joholl%2Ftpmstream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joholl%2Ftpmstream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joholl","download_url":"https://codeload.github.com/joholl/tpmstream/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065286,"owners_count":21041871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["tpm","tpm2"],"created_at":"2024-10-12T08:26:18.273Z","updated_at":"2025-04-09T16:06:56.121Z","avatar_url":"https://github.com/joholl.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/joholl/tpmstream/actions/workflows/test.yml/badge.svg)](https://github.com/joholl/tpmstream/actions/workflows/test.yml)\n[![PyPI version](https://img.shields.io/pypi/v/tpmstream)](https://pypi.org/project/tpmstream)\n\n# tpmstream\n\nA tool to help you understand TPM commands and responses. You can either use the\n`convert` command if you want to decode TPM commands/responses or the `example`\ncommand to find examples.\n\nTry it online at [joholl.github.io/tpmstream-web](https://joholl.github.io/tpmstream-web)!\n\n## Install\n\n```pip install .```\n\nFor development, it is recommended to use a virtual environment and install with the `--editable` switch.\n\n## Decode TPM Commands/Responses:\n\nThe `convert` command reads binary (or pcapng) data from a file:\n\n```bash\n❯ tpmstream convert create_primary.bin\n```\n\n![Example](doc/example.png?raw=true \"Example Screenshot\")\n\n\nOr you can read data from stdin. Just pass `-`:\n\n```bash\n❯ printf \"80020000007700000131400000010000003d0200000000145536c0a5ba338e58abfe729f76ccca61ebaf821f01002082fc712f21e4c7e47bbf84dfa0fb15ddfc7013eb61ed3eb2edaf0286e88ba20c000400000000001a0023000b0004007200000010001a000b00000003001000000000000000000000\"  | xxd -r -p | tpmstream convert -\n```\n\n## Find Examples for TPM Commands/Responses:\n\nYou want to see an exemplary TPM command? Easy, try:\n```bash\n❯ tpmstream ex NV_Write\n```\n\nDon't worry, the tool helps you out if you do not know how to spell a given command:\n\n```bash\n❯ tpmstream ex NVDefine\nUnknown commandCode: NVDefine.\n\nDid you mean:\n\n  tpmstream ex NV_DefineSpace\n```\n\n\n## Python API\n\n### Marshalling\n\nMarshalling functions convert a particular data stream (binary, pcapng, ...)\ninto a canonical format: a sequence of _MarshalEvents_. These events can be\nconverted to a python representation of the respective datatype (e.g. a\n`TPMS_SIG_SCHEME_ECDSA` object).\n\n```python\nfrom tpmstream.common.object import events_to_obj\nfrom tpmstream.io.binary import Binary\nfrom tpmstream.spec.commands import Command\nfrom tpmstream.spec.structures.constants import TPM_SU\n\nevents = Binary.marshal(tpm_type=Command, buffer=b\"\\x80\\x01\\x00\\x00\\x00\\x0c\\x00\\x00\\x01\\x44\\x00\\x00\")\ncommand = events_to_obj(events)\n\nprint(command.parameters.startupType)  # prints TPM_SU.CLEAR\n```\n\nLikewise, these python objects can be turned into a sequence of events, again.\n\n\n```python\nfrom tpmstream.common.object import obj_to_events\nfrom tpmstream.io.binary import Binary\nfrom tpmstream.spec.commands import Command\nfrom tpmstream.spec.commands.commands_handles import TPMS_COMMAND_HANDLES_STARTUP\nfrom tpmstream.spec.commands.commands_params import TPMS_COMMAND_PARAMS_STARTUP\nfrom tpmstream.spec.structures.base_types import UINT32\nfrom tpmstream.spec.structures.constants import TPM_CC, TPM_ST, TPM_SU\nfrom tpmstream.spec.structures.interface_types import TPMI_ST_COMMAND_TAG\n\nstartup_command = Command(\n     tag=TPMI_ST_COMMAND_TAG(TPM_ST.NO_SESSIONS),\n     commandSize=UINT32(12),\n     commandCode=TPM_CC.Startup,\n     handles=TPMS_COMMAND_HANDLES_STARTUP(),\n     parameters=TPMS_COMMAND_PARAMS_STARTUP(startupType=TPM_SU.CLEAR),\n)\n\nevents = obj_to_events(startup_command)\n\n# Note that `events` is a generator. You can obtain a list by via `list(events)`\n```\n\n### Unmarshalling\n\nUnmarshalling functions convert a given set of _MarshalEvents_ into a custom\nformat (binary, pretty print, ...).\n\n```python\nfrom tpmstream.io.binary import Binary\nfrom tpmstream.io.pretty import Pretty\nfrom tpmstream.spec.commands import Command\n\nevents = Binary.marshal(tpm_type=Command, buffer=b\"\\x80\\x01\\x00\\x00\\x00\\x0c\\x00\\x00\\x01\\x44\\x00\\x00\")\npretty = Pretty.unmarshal(events=events)\n\nfor line in pretty:\n     print(line)\n```\n\n\n### Example flow\n\nMarshalling (e.g. binary to events) and unmarshalling (e.g. events to pretty\nprint) is decoupled. Events can be turnt into python objects (like\n`TPMS_SIG_SCHEME_ECDSA`) and vice versa.\n\n```\n               +---------------------+                                                         +----------------------+\n---[binary]--\u003e | binary marshalling  | ---[events]---+-------------------------+---[events]--\u003e | binary unmarshalling | ---[pretty print]--\u003e\n               +---------------------+               |                         |               +----------------------+\n                                                     |    +---------------+    |\n                                                     +--\u003e | python object | ---+\n                                                          +---------------+\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoholl%2Ftpmstream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoholl%2Ftpmstream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoholl%2Ftpmstream/lists"}