mu

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2022 License: LGPL-3.0 Imports: 11 Imported by: 2

Documentation

Overview

Package mu provides helpers to marshalling to and unmarshalling from the TPM wire format.

Go types are marshalled to and from the TPM wire format according to the following rules:

  • UINT8 <-> uint8
  • BYTE <-> byte
  • INT8 <-> int8
  • BOOL <-> bool
  • UINT16 <-> uint16
  • INT16 <-> int16
  • UINT32 <-> uint32
  • INT32 <-> int32
  • UINT64 <-> uint64
  • INT64 <-> int64
  • TPM2B prefixed types (sized buffers with a 2-byte size field) fall in to 2 categories:
  • Byte buffer <-> []byte, or any type with an identical underlying type.
  • Sized structure <-> struct referenced from a pointer field in another structure, where the field has the `tpm2:"sized"` tag. A zero sized struct is represented as a nil pointer.
  • TPMA prefixed types (attributes) <-> whichever go type corresponds to the underlying TPM type (UINT8, UINT16, or UINT32).
  • TPM_ALG_ID (algorithm enum) <-> tpm2.AlgorithmId
  • TPML prefixed types (lists with a 4-byte length field) <-> slice of whichever go type corresponds to the underlying TPM type.
  • TPMS prefixed types (structures) <-> struct
  • TPMT prefixed types (structures with a tag field used as a union selector) <-> struct
  • TPMU prefixed types (unions) <-> struct which implements the Union interface. These must be contained in another structure and referenced from a pointer field. The first field of the enclosing structure is used as the selector value, although this can be overridden by using the `tpm2:"selector:<field_name>"` tag.

TPMI prefixed types (interface types) are generally not explicitly supported. These are used by the TPM for type checking during unmarshalling, but this package doesn't distinguish between TPMI prefixed types with the same underlying type.

The marshalling code parses the "tpm2" tag on struct fields, the value of which is a comma separated list of options. These options are:

  • selector:<field_name> - used on fields that are pointers to structs that implement the Union interface to specify the field used as the selector value. The default behaviour without this option is to use the first field as the selector.
  • sized - used on fields that are pointers to indicate that it should be marshalled and unmarshalled as a sized value. A nil pointer represents a zero-sized value. This is used to implement sized structures.
  • raw - used on slice fields to indicate that it should be marshalled and unmarshalled without a length (if it represents a list) or size (if it represents a sized buffer) field. The slice must be pre-allocated to the correct length by the caller during unmarshalling.

Index

Constants

This section is empty.

Variables

View Source
var NilUnionValue empty

NilUnionValue is a special value, the type of which should be returned from implementations of Union.Select to indicate that a union contains no data for a particular selector value.

Functions

func CopyValue

func CopyValue(dst, src interface{}) error

CopyValue copies the value of src to dst. The destination must be a pointer to the actual destination value. This works by serializing the source value in the TPM wire format and the deserializing it again into the destination.

This will return an error for any reason that would cause MarshalToBytes or UnmarshalFromBytes to return an error.

func MarshalToBytes

func MarshalToBytes(vals ...interface{}) ([]byte, error)

MarshalToBytes marshals vals to TPM wire format, according to the rules specified in the package description.

Pointers are automatically dereferenced. Nil pointers are marshalled to the zero value for the pointed to type, unless the pointer is to a sized structure (a struct field with the 'tpm2:"sized"` tag pointing to another struct), in which case a value of zero size is marshalled.

The number of bytes written to w are returned. If this function does not complete successfully, it will return an error and the number of bytes written.

This function only returns an error if a sized value (sized buffer, sized structure or list) is too large for its corresponding size field.

func MarshalToWriter

func MarshalToWriter(w io.Writer, vals ...interface{}) (int, error)

MarshalToWriter marshals vals to w in the TPM wire format, according to the rules specified in the package description.

Pointers are automatically dereferenced. Nil pointers are marshalled to the zero value for the pointed to type, unless the pointer is to a sized structure (a struct field with the 'tpm2:"sized"` tag pointing to another struct), in which case a value of zero size is marshalled.

The number of bytes written to w are returned. If this function does not complete successfully, it will return an error and the number of bytes written.

This function only returns an error if a sized value (sized buffer, sized structure or list) is too large for its corresponding size field, or if the supplied io.Writer returns an error.

func MustCopyValue

func MustCopyValue(dst, src interface{})

MustCopyValue is the same as CopyValue except that it panics if it encounters an error.

func MustMarshalToBytes

func MustMarshalToBytes(vals ...interface{}) []byte

MustMarshalToBytes is the same as MarshalToBytes, except that it panics if it encounters an error.

func MustMarshalToWriter

func MustMarshalToWriter(w io.Writer, vals ...interface{}) int

MustMarshalToWriter is the same as MarshalToWriter, except that it panics if it encounters an error.

func Raw

func Raw(val interface{}) interface{}

func Sized

func Sized(val interface{}) interface{}

Sized converts the supplied value to a sized value.

To marshal a sized value, the supplied value must be a pointer to the actual value.

To unmarshal a sized value, the supplied value must be a pointer to the destionation pointer that will point to the unmarshalled value.

func UnmarshalFromBytes

func UnmarshalFromBytes(b []byte, vals ...interface{}) (int, error)

UnmarshalFromReader unmarshals data in the TPM wire format from b to vals, according to the rules specified in the package description. The values supplied to this function must be pointers to the destination values.

Pointers are automatically dererefenced. If a pointer is nil, then memory is allocated for the value and the pointer is initialized accordingly, unless the pointer is to a sized structure (a struct field with the 'tpm2:"sized"' tag pointing to another struct) and the value being unmarshalled has a zero size, in which case the pointer is not initialized. If a pointer is already initialized by the caller, then this function will unmarshal to the already allocated memory.

Slices are allocated automatically, unless the caller has already allocated a slice that has a large enough capacity to hold the unmarshalled values, in which case the already allocated slice will be used and its length set accordingly.

This can unmarshal raw slices (those without a corresponding size or length fields, represented by the RawBytes type or a slice value referenced from a struct field with the 'tpm2:"raw"' tag), but the caller must pre-allocate a slice of the correct size first. This function cannot allocate a slice because it doesn't have a way to determine the size to allocate.

The number of bytes consumed from b are returned. If this function does not complete successfully, it will return an error and the number of bytes consumed. In this case, partial results may have been unmarshalled to the supplied destination values.

func UnmarshalFromReader

func UnmarshalFromReader(r io.Reader, vals ...interface{}) (int, error)

UnmarshalFromReader unmarshals data in the TPM wire format from r to vals, according to the rules specified in the package description. The values supplied to this function must be pointers to the destination values.

Pointers are automatically dererefenced. If a pointer is nil, then memory is allocated for the values and the pointer is initialized accordingly, unless the pointer is to a sized structure (a struct field with the 'tpm2:"sized"' tag pointing to another struct) and the values being unmarshalled has a zero size, in which case the pointer is not initialized. If a pointer is already initialized by the caller, then this function will unmarshal to the already allocated memory.

Slices are allocated automatically, unless the caller has already allocated a slice that has a large enough capacity to hold the unmarshalled values, in which case the already allocated slice will be used and its length set accordingly.

This can unmarshal raw slices (those without a corresponding size or length fields, represented by the RawBytes type or a slice value referenced from a struct field with the 'tpm2:"raw"' tag), but the caller must pre-allocate a slice of the correct size first. This function cannot allocate a slice because it doesn't have a way to determine the size to allocate.

The number of bytes read from r are returned. If this function does not complete successfully, it will return an error and the number of bytes read. In this case, partial results may have been unmarshalled to the supplied destination values.

Types

type CustomMarshaller

type CustomMarshaller interface {
	Marshal(w io.Writer) error
}

CustomMarshaller is implemented by types that require custom marshalling behaviour because they are non-standard and not directly supported by the marshalling code. This interface should be implemented by types with a value receiver if you want to be able to pass it directly by value to MarshalToBytes or MarshalToWriter. Implementations must also implement the CustomUnmarshaller interface.

If the custom implementation makes a recursive call in the MarshalToWriter, it should propagate errors from this without wrapping. This allows the full context of the error to be surfaced from the originating call.

type CustomUnmarshaller added in v0.0.3

type CustomUnmarshaller interface {
	Unmarshal(r Reader) error
}

CustomUnmarshaller is implemented by types that require custom unmarshalling behaviour because they are non-standard and not directly supported by the marshalling code. This interface must be implemented by types with a pointer receiver, and types must also implement the CustomMarshaller interface.

If the custom implementation makes a recursive call in the UnmarshalFromReader, it should propagate errors from this without wrapping. This allows the full context of the error to be surfaced from the originating call.

type Error

type Error struct {
	// Index indicates the argument on which this error occurred.
	Index int

	Op string
	// contains filtered or unexported fields
}

Error is returned from any function in this package to provide context of where an error occurred.

func (*Error) Container

func (e *Error) Container(depth int) (containerType reflect.Type, index int, entry runtime.Frame)

Container returns the type of the container at the specified depth.

If the returned type is a structure, the returned index corresponds to the index of the field in that structure.

If the returned type is a slice, the returned index corresponds to the index in that slice.

If the returned type implements the CustomMarshaller and CustomUnmarshaller interfaces, the returned index corresponds to the argument index in the recursive call in to one of the marshalling or unmarshalling APIs. The returned frame indicates where this recursive call originated from.

func (*Error) Depth

func (e *Error) Depth() int

Depth returns the depth of the value on which this error occurred.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Type

func (e *Error) Type() reflect.Type

Type returns the type of the value on which this error occurred.

func (*Error) Unwrap

func (e *Error) Unwrap() error

type InvalidSelectorError

type InvalidSelectorError struct {
	Selector reflect.Value
}

InvalidSelectorError may be returned as a wrapped error from UnmarshalFromBytes or UnmarshalFromReader when a union type indicates that a selector value is invalid.

func (*InvalidSelectorError) Error

func (e *InvalidSelectorError) Error() string

type RawBytes

type RawBytes []byte

RawBytes is a special byte slice type which is marshalled and unmarshalled without a size field. The slice must be pre-allocated to the correct length by the caller during unmarshalling.

type Reader added in v0.0.3

type Reader interface {
	io.Reader
	Len() int
}

Reader is an interface that groups the io.Reader interface with an additional method to obtain the remaining number of bytes that can be read for implementations that support this.

type TPMKind

type TPMKind int

TPMKind indicates the TPM type class associated with a Go type

const (
	// TPMKindUnsupported indicates that a go type has no corresponding
	// TPM type class.
	TPMKindUnsupported TPMKind = iota

	// TPMKindPrimitive indicates that a go type corresponds to one
	// of the primitive TPM types (UINT8, BYTE, INT8, BOOL, UINT16,
	// INT16, UINT32, INT32, UINT64, INT64, TPM_ALG_ID, any TPMA_
	// prefixed type).
	TPMKindPrimitive

	// TPMKindSized indicates that a go type corresponds to a
	// TPM2B prefixed TPM type.
	TPMKindSized

	// TPMKindList indicates that a go type corresponds to a
	// TPML prefixed TPM type.
	TPMKindList

	// TPMKindStruct indicates that a go type corresponds to a
	// TPMS or TPMT prefixed TPM type - this package doesn't
	// distinguish between the two.
	TPMKindStruct

	// TPMKindUnion indicates that a go type corresponds to a
	// TPMU prefixed TPM type.
	TPMKindUnion

	// TPMKindCustom correponds to a go type that defines its own
	// marshalling behaviour.
	TPMKindCustom

	// TPMKindRaw corresponds to a go slice that is marshalled
	// without a size field (it is not TPMKindSized or TPMKindList).
	TPMKindRaw
)

func DetermineTPMKind

func DetermineTPMKind(i interface{}) TPMKind

DetermineTPMKind returns the TPMKind associated with the supplied go value. It will automatically dereference pointer types. Single field structures will be unwrapped and the TPMKind associated with the structure field will be returned.

type Union

type Union interface {
	// Select is called by the marshalling code to map the supplied selector to a field. The returned value must be a pointer to
	// the field to be marshalled or unmarshalled. To work correctly during marshalling and unmarshalling, implementations must
	// take a pointer receiver. If no data should be marshalled or unmarshalled, it should return NilUnionValue.
	Select(selector reflect.Value) interface{}
}

Union is implemented by structure types that correspond to TPMU prefixed TPM types.

Jump to

Keyboard shortcuts

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