Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tcti as used by tpm2-tss tcti-py #21

Merged
merged 3 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ jobs:
- name: Install dependencies
run: sudo apt install -y libpcap-dev libtss2-dev

- uses: actions/setup-python@v3
- uses: actions/setup-python@v5
with:
python-version: '3.12'

- uses: syphar/restore-virtualenv@v1
id: cache-virtualenv
Expand All @@ -23,9 +25,11 @@ jobs:

# the package installation will only be executed when the
# requirements-files have changed.
- run: pip install .; pip install pytest autoflake black isort tpm2_pytss
- run: pip install --upgrade pip && pip install . && pip install pytest autoflake black isort cryptography==3.4.8 tpm2_pytss
#if: steps.cache-virtualenv.outputs.cache-hit != 'true'

- run: pip freeze

- name: Test
run: python -m pytest

Expand All @@ -39,7 +43,9 @@ jobs:
- name: Install dependencies
run: sudo apt install -y libpcap-dev bats

- uses: actions/setup-python@v3
- uses: actions/setup-python@v5
with:
python-version: '3.12'

- uses: syphar/restore-virtualenv@v1
id: cache-virtualenv
Expand All @@ -66,7 +72,9 @@ jobs:
- name: Install dependencies
run: sudo apt install -y libpcap-dev

- uses: actions/setup-python@v3
- uses: actions/setup-python@v5
with:
python-version: '3.12'

- uses: syphar/restore-virtualenv@v1
id: cache-virtualenv
Expand Down
31 changes: 22 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ converted to a python representation of the respective datatype (e.g. a
`TPMS_SIG_SCHEME_ECDSA` object).

```python
from tpmstream.common.event import events_to_obj
from tpmstream.common.object import events_to_obj
from tpmstream.io.binary import Binary
from tpmstream.spec.commands.commands import Command
from tpmstream.spec.commands import Command
from tpmstream.spec.structures.constants import TPM_SU

events = Binary.marshal(tpm_type=Command, buffer=b"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00")
command = events_to_obj(Command, events)
command = events_to_obj(events)

print(command.parameters.startupType) # prints TPM_SU.CLEAR
```
Expand All @@ -76,11 +76,24 @@ Likewise, these python objects can be turned into a sequence of events, again.


```python
from tpmstream.common.event import obj_to_events

# ...

events = obj_to_events(command)
from tpmstream.common.object import obj_to_events
from tpmstream.io.binary import Binary
from tpmstream.spec.commands import Command
from tpmstream.spec.commands.commands_handles import TPMS_COMMAND_HANDLES_STARTUP
from tpmstream.spec.commands.commands_params import TPMS_COMMAND_PARAMS_STARTUP
from tpmstream.spec.structures.base_types import UINT32
from tpmstream.spec.structures.constants import TPM_CC, TPM_ST, TPM_SU
from tpmstream.spec.structures.interface_types import TPMI_ST_COMMAND_TAG

startup_command = Command(
tag=TPMI_ST_COMMAND_TAG(TPM_ST.NO_SESSIONS),
commandSize=UINT32(12),
commandCode=TPM_CC.Startup,
handles=TPMS_COMMAND_HANDLES_STARTUP(),
parameters=TPMS_COMMAND_PARAMS_STARTUP(startupType=TPM_SU.CLEAR),
)

events = obj_to_events(startup_command)

# Note that `events` is a generator. You can obtain a list by via `list(events)`
```
Expand All @@ -93,7 +106,7 @@ format (binary, pretty print, ...).
```python
from tpmstream.io.binary import Binary
from tpmstream.io.pretty import Pretty
from tpmstream.spec.commands.commands import Command
from tpmstream.spec.commands import Command

events = Binary.marshal(tpm_type=Command, buffer=b"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00")
pretty = Pretty.unmarshal(events=events)
Expand Down
4 changes: 4 additions & 0 deletions src/tpmstream/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
__version__ = "0.1.10"

# make tcti_init visible for py-tcti
# see https://github.com/tpm2-software/tpm2-tss/pull/2749
from tpmstream.tcti import tcti_init # isort:skip
70 changes: 70 additions & 0 deletions src/tpmstream/tcti/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import_error = None
try:
from tpm2_pytss import TCTILdr
except ImportError as error:
import_error = error

from tpmstream.io.binary import Binary
from tpmstream.io.pretty import Pretty
from tpmstream.spec.commands import Command, Response


# To use tpmstream with tcti-py, we define a tcti
# see https://github.com/tpm2-software/tpm2-tss/pull/2749
class TpmstreamTCTI(object):
def __init__(self, args: str | None):
def parse_args(args: str | None):
if args is None:
return {"name": None, "conf": None}
if ":" not in args:
return {"name": args, "conf": None}

name, conf = args.split(":", maxsplit=1)
return {"name": name, "conf": conf}

nameconf = parse_args(args)
print(f"PYTHON: Initializing TCTI Ldr with mod: {nameconf}")
self._tcti = TCTILdr(**nameconf)
self._command_code = None

@property
def magic(self):
return 0x74706D7374726561

def receive(self, timeout: int) -> bytes:
result = self._tcti.receive(timeout=timeout)

events = Binary.marshal(
tpm_type=Response,
buffer=result,
command_code=self._command_code,
abort_on_error=False,
)
for line in Pretty.unmarshal(events):
if isinstance(line, bytes):
print(" " + binascii.hexlify(line).decode(), end="")
else:
print(line)

return result

def transmit(self, buffer: bytes):
events = Binary.marshal(
tpm_type=Command,
buffer=buffer,
abort_on_error=False,
)
for line in Pretty.unmarshal(events):
if isinstance(line, bytes):
print(" " + binascii.hexlify(line).decode(), end="")
else:
print(line)
self._command_code = int.from_bytes(buffer[6:10], byteorder="big")

self._tcti.transmit(buffer)


def tcti_init(args: str) -> TpmstreamTCTI:
if import_error:
raise import_error
return TpmstreamTCTI(args)
55 changes: 55 additions & 0 deletions test/test_readme.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class TestReadme:
def test_marshal_from_bytes(self):
from tpmstream.common.object import events_to_obj
from tpmstream.io.binary import Binary
from tpmstream.spec.commands import Command
from tpmstream.spec.structures.constants import TPM_SU

events = Binary.marshal(
tpm_type=Command, buffer=b"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
)
command = events_to_obj(events)

print(command.parameters.startupType) # prints TPM_SU.CLEAR
assert command.parameters.startupType == TPM_SU.CLEAR

def test_marshal_from_command(self):
from tpmstream.common.object import obj_to_events
from tpmstream.io.binary import Binary
from tpmstream.spec.commands import Command
from tpmstream.spec.commands.commands_handles import (
TPMS_COMMAND_HANDLES_STARTUP,
)
from tpmstream.spec.commands.commands_params import TPMS_COMMAND_PARAMS_STARTUP
from tpmstream.spec.structures.base_types import UINT32
from tpmstream.spec.structures.constants import TPM_CC, TPM_ST, TPM_SU
from tpmstream.spec.structures.interface_types import TPMI_ST_COMMAND_TAG

startup_command = Command(
tag=TPMI_ST_COMMAND_TAG(TPM_ST.NO_SESSIONS),
commandSize=UINT32(12),
commandCode=TPM_CC.Startup,
handles=TPMS_COMMAND_HANDLES_STARTUP(),
parameters=TPMS_COMMAND_PARAMS_STARTUP(startupType=TPM_SU.CLEAR),
)

events = obj_to_events(startup_command)
assert list(events) == list(
Binary.marshal(
tpm_type=Command,
buffer=b"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00",
)
)

def test_unmarshal(self):
from tpmstream.io.binary import Binary
from tpmstream.io.pretty import Pretty
from tpmstream.spec.commands import Command

events = Binary.marshal(
tpm_type=Command, buffer=b"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
)
pretty = Pretty.unmarshal(events=events)

for line in pretty:
print(line)
Loading