tpmproxy

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2024 License: Apache-2.0 Imports: 14 Imported by: 0

README

= TPMProxy

TPMProxy is a library that proxies TPM communications, makes them analyzable, and supports tampering.
It also provides several tools as usage examples of the library.

== Disclaimer

The purpose of TPMProxy is to support TPM application development and security research.
TPMProxy intentionally lowers security for communication analysis.
Do not use in a production environment.

== Features

All features are available only on Linux. Windows and Mac are not supported.

* Proxy the UNIX domain socket communication between https://www.qemu.org/[QEMU] and https://github.com/stefanberger/swtpm[SWTPM] to TCP communication, making it analyzable with https://www.wireshark.org/[Wireshark].
* Assist in analyzing TPM commands and responses using https://github.com/google/go-tpm[Go-TPM]. Currently, this feature is limited, but it allows for more detailed parameter analysis than Wireshark.
* Support the tampering of TPM commands and responses. You need to implement the tampering program yourself.
* Create a virtual TPM device using https://github.com/libfuse/libfuse[CUSE(libfuse)] and pass through to the actual TPM. It allows to analyze the communication to the actual TPM with Wireshark, analyze it with Go-TPM, and tamper with it.

== Usage example

[bash]
----
$ swtpm socket --tpmstate dir=path/to/state --tpm2 --server port=2321 --ctrl type=tcp,port=2322
$ go run github.com/CyberDefenseInstitute/tpmproxy/example/qemu_swtpm_dissect@latest
$ qemu-system-x86_64 \
    ...options... \
    -chardev socket,id=chrtpm,path=/tmp/qemu_swtpm_fwd.sock \
    -tpmdev emulator,id=tpm0,chardev=chrtpm \
    -device tpm-tis,tpmdev=tpm0
----

image::img/dissect.webp[dissect]

image::img/tamper.webp[tamper]

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CuseRelay

func CuseRelay(devname string) int

CuseRelay is a special relayer function that uses CUSE to relay TPM commands and responses. CuseRelay requires root privilege to run. It is a blocking function that will return when the relay is done. The devname is the device name that will be used to create the relay device. The devname must be a valid device name that can be used in the filesystem. The function will return the exit code of the relay.

func CuseTpmOpen

func CuseTpmOpen(req C.fuse_req_t, fi *C.FUSE_FILE_INFO)

func CuseTpmRead

func CuseTpmRead(req C.fuse_req_t, size C.size_t, off C.off_t, fi *C.FUSE_FILE_INFO)

func CuseTpmWrite

func CuseTpmWrite(req C.fuse_req_t, buf *C.cchar_t, size C.size_t, off C.off_t, fi *C.FUSE_FILE_INFO)

func FilterClosedErr

func FilterClosedErr(err error) error

func HasTag

func HasTag(t reflect.StructField, query string) bool

func IsMarshalledByReflection

func IsMarshalledByReflection(v reflect.Value) bool

func Marshal

func Marshal(buf *bytes.Buffer, v reflect.Value) error

func ReqHandles

func ReqHandles(req *bytes.Buffer, cmd any) error

func ReqHeader

func ReqHeader(req *bytes.Buffer) (*tpm2.TPMCmdHeader, error)

func ReqParameters

func ReqParameters(req *bytes.Buffer, sess []tpm2.Session, cmd any, rh *tpm2.TPMCmdHeader) error

func RspHandles

func RspHandles(rsp *bytes.Buffer, rspStruct any) error

func RspHeader

func RspHeader(rsp *bytes.Buffer) error

func RspParameters

func RspParameters(parms []byte, sess []tpm2.Session, rspStruct any) error

func RspParametersArea

func RspParametersArea(hasSessions bool, rsp *bytes.Buffer) ([]byte, error)

func RspSessions

func RspSessions(rsp *bytes.Buffer, rc tpm2.TPMRC, cc tpm2.TPMCC, names []tpm2.TPM2BName, parms []byte, sess []tpm2.Session) error

func SetCuseForwarder

func SetCuseForwarder(forwarder Forwarder)

func TaggedMembers

func TaggedMembers(v reflect.Value, tag string, invert bool) []reflect.Value

func Unmarshal

func Unmarshal(buf *bytes.Buffer, v reflect.Value) error

Types

type Exchanger

type Exchanger struct {
	// Src is the exchange source.
	Src io.ReadWriter
	// Dst is the exchange destination.
	Dst io.ReadWriter
	// HandlerFactory is the factory that creates RequestResponseHandlers.
	HandlerFactory RequestResponseHandlerFactory
}

Exchanger is a struct that exchanges data between two io.ReadWriters. It uses a RequestResponseHandlerFactory to create RequestResponseHandlers for each request-response pair.

func (*Exchanger) Exchange

func (ex *Exchanger) Exchange() error

Exchange exchanges data between the source and destination.

type Forwarder

type Forwarder io.ReadWriteCloser

Forwarder is an interface that forwards data to a destination.

var (
	CuseForwarder Forwarder
)

type ForwarderFactory

type ForwarderFactory interface {
	NewForwarder() (Forwarder, error)
}

ForwarderFactory is an interface that creates Forwarders.

type Interceptor

type Interceptor interface {
	// HandleRequest handles a request and returns a modified request.
	HandleRequest(request *Request) []byte
	// HandleResponse handles a response and returns a modified response.
	HandleResponse(request *Request, response []byte) []byte
}

Interceptor is an interface that intercepts requests and responses.

type IoForwarder

type IoForwarder struct {
	Fd int
}

IoForwarder is a Forwarder that forwards data to a file descriptor.

func (*IoForwarder) Close

func (f *IoForwarder) Close() error

func (*IoForwarder) Read

func (f *IoForwarder) Read(p []byte) (int, error)

func (*IoForwarder) Write

func (f *IoForwarder) Write(p []byte) (int, error)

type IoForwarderFactory

type IoForwarderFactory struct {
	Path string
}

IoForwarderFactory is a ForwarderFactory that creates IO Forwarders.

func NewIoForwarderFactory

func NewIoForwarderFactory(path string) *IoForwarderFactory

NewIoForwarderFactory creates a new IoForwarderFactory.

func (*IoForwarderFactory) NewForwarder

func (f *IoForwarderFactory) NewForwarder() (Forwarder, error)

NewForwarder creates a new IO Forwarder.

type NopRequestResponseHandler

type NopRequestResponseHandler struct {
}

NopRequestResponseHandler is a RequestResponseHandler that does nothing.

func (*NopRequestResponseHandler) HandleRequest

func (h *NopRequestResponseHandler) HandleRequest(request []byte) []byte

func (*NopRequestResponseHandler) HandleResponse

func (h *NopRequestResponseHandler) HandleResponse(response []byte) []byte

type NopRequestResponseHandlerFactory

type NopRequestResponseHandlerFactory struct {
	Handler NopRequestResponseHandler
}

NopRequestResponseHandlerFactory is a RequestResponseHandlerFactory that creates NopRequestResponseHandlers.

func (*NopRequestResponseHandlerFactory) NewRequestResponseHandler

func (f *NopRequestResponseHandlerFactory) NewRequestResponseHandler() RequestResponseHandler

type QemuCtrlRelayer

type QemuCtrlRelayer struct {
	CtrlSockFile         string
	ForwarderFactory     ForwarderFactory
	CtrlForwarderFactory ForwarderFactory
	TerminateOnClose     bool
	Interceptor          Interceptor
	Terminate            chan interface{}
}

QemuCtrlRelayer is a relayer for the UNIXIO control channel of QEMU. It listens on a UNIX domain socket for incoming connections from QEMU. Upon receiving a connection, it creates a pair of forwarders for the control channel and the server channel, and starts exchanging messages between the two channels. The relayer can be configured to terminate upon closing of either channel. The relayer can also be configured with an interceptor to intercept and modify messages.

func NewQemuCtrlRelayer

func NewQemuCtrlRelayer(ctrlSockFile string,
	forwarderFactory ForwarderFactory, ctrlForwarderFactory ForwarderFactory,
	terminateOnClose bool, interceptor Interceptor) *QemuCtrlRelayer

func (*QemuCtrlRelayer) HandleConnLoop

func (r *QemuCtrlRelayer) HandleConnLoop(qemuCtrlConn net.Conn) error

func (*QemuCtrlRelayer) Relay

func (r *QemuCtrlRelayer) Relay() error

type Request

type Request struct {
	// Hdr is the TPM command header.
	Hdr *tpm2.TPMCmdHeader
	// Raw is the raw command.
	Raw []byte
}

Request is a struct that contains a TPM command header and raw command.

type RequestResponseHandler

type RequestResponseHandler interface {
	// HandleRequest handles a request and returns a modified request.
	// The request is a byte slice that contains the raw request.
	HandleRequest(request []byte) []byte
	// HandleResponse handles a response and returns a modified response.
	// The response is a byte slice that contains the raw response.
	HandleResponse(response []byte) []byte
}

RequestResponseHandler is an interface that handles request-response pairs.

type RequestResponseHandlerFactory

type RequestResponseHandlerFactory interface {
	// NewRequestResponseHandler creates a new RequestResponseHandler.
	NewRequestResponseHandler() RequestResponseHandler
}

RequestResponseHandlerFactory is an interface that creates RequestResponseHandlers.

type RoughParser

type RoughParser struct {
	RawRequest  []byte
	RawResponse []byte

	// Cmd is the command structure pointer
	Cmd any
	// Rsp is the response structure pointer
	Rsp    any
	CmdHdr *tpm2.TPMCmdHeader

	// CmdParameterOffset is the offset of the command parameters
	CmdParameterOffset int
	// RspParameterOffset is the offset of the response parameters
	RspParameterOffset int
}

RoughParser is a rough parser for TPM commands and responses. It parses the raw request and response buffers and populates the provided command and response structures. The command and response structures must be pointers to the corresponding command and response structures. It also holds the offsets of the command and response parameters as the parsing results. The offsets are useful for building request and response after parameter tampering.

func (*RoughParser) Parse

func (p *RoughParser) Parse() error

type TcpForwarderFactory

type TcpForwarderFactory struct {
	Addr string
}

TcpForwarderFactory is a ForwarderFactory that creates TCP Forwarders.

func NewTcpForwarderFactory

func NewTcpForwarderFactory(addr string) *TcpForwarderFactory

NewTcpForwarderFactory creates a new TcpForwarderFactory.

func (*TcpForwarderFactory) NewForwarder

func (f *TcpForwarderFactory) NewForwarder() (Forwarder, error)

NewForwarder creates a new TCP Forwarder.

type TcpRelayer

type TcpRelayer struct {
	Addr             string
	ForwarderFactory ForwarderFactory
	TerminateOnClose bool
	Interceptor      Interceptor
	Terminate        chan interface{}
}

TcpRelayer is a relayer for TCP connections. TcpRelayer is used to turn non-network traffic into network traffic so that it can be captured.

func NewTcpRelayer

func NewTcpRelayer(addr string, forwarderFactory ForwarderFactory, interceptor Interceptor) *TcpRelayer

func (*TcpRelayer) HandleConnLoop

func (r *TcpRelayer) HandleConnLoop(conn net.Conn) error

func (*TcpRelayer) Relay

func (r *TcpRelayer) Relay() error

type TpmRequestResponseHandler

type TpmRequestResponseHandler struct {
	Interceptor Interceptor
	Request     Request
}

TpmRequestResponseHandler is a RequestResponseHandler that handles TPM request-response pairs.

func (*TpmRequestResponseHandler) HandleRequest

func (h *TpmRequestResponseHandler) HandleRequest(request []byte) []byte

HandleRequest handles a request and returns a Interceptor-modified request.

func (*TpmRequestResponseHandler) HandleResponse

func (h *TpmRequestResponseHandler) HandleResponse(response []byte) []byte

HandleResponse handles a response and returns a Interceptor-modified response.

type TpmRequestResponseHandlerFactory

type TpmRequestResponseHandlerFactory struct {
	// Interceptor is the Interceptor that intercepts requests and responses.
	Interceptor Interceptor
}

TpmRequestResponseHandlerFactory is a RequestResponseHandlerFactory that creates TpmRequestResponseHandlers.

func (*TpmRequestResponseHandlerFactory) NewRequestResponseHandler

func (f *TpmRequestResponseHandlerFactory) NewRequestResponseHandler() RequestResponseHandler

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL