mu

package
v1.6.2 Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2024 License: LGPL-3.0 Imports: 9 Imported by: 10

Documentation

Overview

Package mu contains functions for marshalling go values to and unmarshalling them 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) have 2 representations in go:

    1. []byte, or any type with an identical underlying type. A zero sized value is unmarshalled to nil.

    2. Pointer to a struct, either referenced from a field with the `tpm2:"sized"` tag or wrapped with the Sized() function. A zero sized value 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) <-> uint16

  • TPML prefixed types (lists with a 4-byte length field) <-> slice of whichever go type corresponds to the underlying TPM type. Zero length lists are unmarshalled to nil.

  • TPMS prefixed types (structures) <-> struct

  • TPMT prefixed types (tagged union) <-> struct with at least one member that is a struct or pointer to a struct that represents a union. The first member is the selector field unless overridden on the union member with the `tpm2:"selector:<field_name>"` tag.

  • TPMU prefixed types (unions) <-> struct which implements the Union interface. The default selector field 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.

Byte array types are supported and are marshalled to and from a fixed size bytes sequence. No other array types are supported.

Pointers are automatically dererenced during marshalling and unmarshalling.

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

  • sized1 - the field is a variable sized buffer with a single byte size field, used to support the TPMS_PCR_SELECT type. This is only valid for byte slice fields.
  • ignore - the field is ignored by this package.
  • selector:<field_name> - override the default selector field on a field to a structure that represents a union. The default behaviour without this option is to use the first field as the selector. It is invalid to use this on any field that isn't a structure or pointer to a structure that represents a union.
  • sized - turns a pointer to a structure into a sized (TPM2B) type. A zero sized structure is represented by a nil pointer. It is invalid to use this on any field that isn't a pointer to a structure.
  • raw - turns a slice into a raw type so that it is marshalled and unmarshalled without a size or length field. The slice must be pre-allocated to the correct length by the caller during unmarshalling. This is only valid for slice fields.

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 DeepEqual added in v0.2.0

func DeepEqual(x, y interface{}) (equal bool)

DeepEqual determines whether the supplied values are deeply equal. Values are deeply equal if they have the same type and have the same representation when serialized. This will return false if either value cannot be represented by the TPM wire format.

func IsValid added in v0.2.0

func IsValid(v interface{}) (valid bool)

IsValid determines whether the supplied value is representable by the TPM wire format. It returns false if the type would cause a panic during marshalling or unmarshalling.

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), 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), 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{}) *wrappedValue

Raw converts the supplied value, which should be a slice, to a raw slice. A raw slice is one that is marshalled without a corresponding size or length field.

To unmarshal a raw slice, the supplied value must be a pointer to the preallocated destination slice.

func Sized

func Sized(val interface{}) *wrappedValue

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 destination 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) and the value being unmarshalled has a zero size, in which case the pointer is cleared. 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 in which case it will be used if it has a large enough capacity. Zero length slices are unmarshalled as nil.

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 value and the pointer is initialized accordingly, unless the pointer is to a sized structure (a struct field with the 'tpm2:"sized"' tag) and the value being unmarshalled has a zero size, in which case the pointer is cleared. 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 in which case it will be used if it has a large enough capacity. Zero length slices are unmarshalled as nil.

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 should serialize the value to the supplied writer.
	// The implementation of this should take a value receiver, but if
	// it takes a pointer receiver then the value must be addressable.
	Marshal(w io.Writer) error

	// Unmarshal should unserialize the value from the supplied reader.
	// The implementation of this should take a pointer receiver.
	Unmarshal(r io.Reader) error
}

CustomMarshaller is implemented by types that require custom marshalling behaviour because they are non-standard and not directly supported by this package.

If the implementation makes a recursive call in to this package, it should return errors from any recursive call 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 interface, 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 Sized1Bytes added in v0.9.9

type Sized1Bytes []byte

Sized1Bytes is a special byte slice which is marshalled and unmarhalled with a single byte size field. This is to faciliate the TPMS_PCR_SELECT type, which looks like any other variable sized type (TPML and TPM2B types) with a size field and variable sized payload, only TPMS_PCR_SELECT has a single byte size field.

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 prefixed TPM type.
	TPMKindStruct

	// TPMKindTaggedUnion indicates that a go type corresponds
	// to a TPMT prefixed TPM type.
	TPMKindTaggedUnion

	// 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 behaves like a sequence of
	// individual values.
	TPMKindRaw

	// TPMKindSized1Bytes indicates that a go type corresponds to
	// a variable sized byte slice with a single byte size field,
	// and is a special type used to support TPMS_PCR_SELECT.
	TPMKindSized1Bytes

	TPMKindFixedBytes
)

func DetermineTPMKind

func DetermineTPMKind(i interface{}) TPMKind

DetermineTPMKind returns the TPMKind associated with the supplied go value. It will automatically dereference pointer types.

This doesn't mean that the supplied go value can actually be handled by this package because it doesn't recurse into containers.

type Union

type Union interface {
	// Select is called by this package to map the supplied selector value
	// to a field. The returned value must be a pointer to the selected field.
	// For this to work correctly, implementations must take a pointer receiver.
	//
	// If the supplied selector value maps to no data, return NilUnionValue.
	//
	// If nil is returned, this is interpreted as an error.
	Select(selector reflect.Value) interface{}
}

Union is implemented by structure types that correspond to TPMU prefixed TPM types. A struct that contains a union member automatically becomes a tagged union. The selector field is the first member of the tagged union, unless overridden with the `tpm2:"selector:<field_name>"` tag.

Go doesn't have support for unions - TPMU types must be implemented with a struct that contains a field for each possible value.

Implementations of this must be addressable when marshalling.

Jump to

Keyboard shortcuts

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