/go-configfs-tsm

Primary LanguageGoApache License 2.0Apache-2.0

go-configfs-tsm

This library wraps the configfs/tsm Linux subsystem for Trusted Security Module operations.

report library

This library wraps the configfs/tsm/report subsystem for safely generating attestation reports.

The TSM report subsystem provides a vendor-agnostic interface for collecting a signed document for the Trusted Execution Environment's (TEE) state for remote verification. For simplicity, we call this document an "attestation report", though other sources may sometimes refer to it as a "quote".

Signing keys are expected to be rooted back to the manufacturer. Certificates may be present in the auxblob attribute or as part of the report in outblob.

The core functionality of attestation report interaction is nonce in, report out. For testability, we abstract the file operations that are needed for creating configfs report entries, reading and writing attributes, and final reclaiming of resources.

func Get(client configfsi.Client, req *report.Request) (*report.Response, error)

Where

type Request struct {
	InBlob     []byte
	Privilege  *Privilege
	GetAuxBlob bool
}


type Response struct {
	Provider string
	OutBlob  []byte
	AuxBlob  []byte
}

type Privilege struct {
	Level int
}

The provider may not implement an AuxBlob delivery mechanism, so if GetAuxBlob is true, then AuxBlob still must be checked for length 0.

Errors

Since this is a file-based system, there's always a chance that an operation may fail with a permission error. By default, the TSM system requires root access.

The host may also add rate limiting to requests, such that an outblob read fails with EBUSY. The kernel may or may not try again on behalf of the user.

Finally, due to the fact that the TSM report system only requests an attestation report when reading outblob or auxblob, there is a chance the input attributes may have been changed to unexpected values from an interfering process. This interference is a bug in user space that the kernel does not block for simplicity. Interference is evident through the generation attribute. When generation does not match the expectations that the report package tracks, report.Get returns a *report.GenerationErr or an error that wraps *report.GenerationErr.

Use func GetGenerationErr(error) *GenerationErr to extract a *GenerationErr from an error if it is or contains a *GenerationErr. If present, the caller should try to identify the source of interference and remove it. Meanwhile, the caller may try again.

configfsi.Client interface

Most users will only want to use the client from linuxtsm.MakeClient.

A client on real hardware is just the filesystem, since the configfs interactions will interact with the hardware. In unit tests though, we can emulate the behavior that has been proposed in v7 of the patch series

type Client interface {
	MkdirTemp(dir, pattern string) (string, error)
	ReadFile(name string) ([]byte, error)
	WriteFile(name string, contents []byte) error
	RemoveAll(path string) error
}

The RemoveAll function is the only oddly named method, since the real interface would just rmdir the report directory (os.Remove in Golang), even when there are apparent files underneath. Non-empty directory removal is generally not allowed, so the RemoveAll name is clearer with what it does.

linuxtsm package

The linuxtsm package defines an implementation of configfsi.Client with

func MakeClient() (configfsi.Client, error)

For further convenience, linuxtsm provides an alias for MakeClient combined with report.Get as

func GetReport(req *report.Request) (*report.Response, error)

The usage is the same as for report.Get.

faketsm package

The faketsm.Client implementation allows tests to provide custom behavior for subsystems by name:

type Client struct {
	Subsystems map[string]configfsi.Client
}

The faketsm.ReportSubsystem type implements a client that emulates the concurrent behavior and generation attribute semantics. To test negative behavior as well, the subsystem allows the user to override Mkdir, ReadFile, existing entries' values, and the error behavior of WriteFile.

Disclaimer

This is not an officially supported Google product.