tpm2

package
v0.0.17 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2022 License: GPL-3.0 Imports: 35 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTPMClearRequiresPPI is returned from Connection.EnsureProvisioned and indicates that clearing the TPM must be performed via
	// the Physical Presence Interface.
	ErrTPMClearRequiresPPI = errors.New("clearing the TPM requires the use of the Physical Presence Interface")

	// ErrTPMProvisioningRequiresLockout is returned from Connection.EnsureProvisioned when fully provisioning the TPM requires
	// the use of the lockout hierarchy. In this case, the provisioning steps that can be performed without the use of the lockout
	// hierarchy are completed.
	ErrTPMProvisioningRequiresLockout = errors.New("provisioning the TPM requires the use of the lockout hierarchy")

	// ErrTPMProvisioning indicates that the TPM is not provisioned correctly for the requested operation. Please note that other errors
	// that can be returned may also be caused by incomplete provisioning, as it is not always possible to detect incomplete or
	// incorrect provisioning in all contexts.
	ErrTPMProvisioning = errors.New("the TPM is not correctly provisioned")

	// ErrTPMLockout is returned from any function when the TPM is in dictionary-attack lockout mode. Until
	// the TPM exits lockout mode, the key will need to be recovered via a mechanism that is independent of
	// the TPM (eg, a recovery key)
	ErrTPMLockout = errors.New("the TPM is in DA lockout mode")

	// ErrNoTPM2Device is returned from ConnectToDefaultTPM or SecureConnectToDefaultTPM if no TPM2 device is avaiable.
	ErrNoTPM2Device = errors.New("no TPM2 device is available")
)
View Source
var ConnectToTPM func() (*Connection, error) = ConnectToDefaultTPM

ConnectToTPM will attempt to connect to a TPM using the currently defined connection function. This is used internally by the tpm2 package when a connection is required, and defaults to ConnectToDefaultTPM. This can be overridden with a custom connection function.

Functions

func AddSnapModelProfile

func AddSnapModelProfile(profile *PCRProtectionProfile, params *SnapModelProfileParams) error

AddSnapModelProfile adds the snap model profile to the PCR protection profile, as measured by snap-bootstrap, in order to generate a PCR policy that is bound to a specific set of device models. It is the responsibility of snap-bootstrap to verify the integrity of the model that it has measured.

The profile consists of 2 measurements:

digestEpoch
digestModel

digestEpoch is currently hardcoded as (where H is the digest algorithm supplied via params.PCRAlgorithm):

digestEpoch = H(uint32(0))

A future version of this package may allow another epoch to be supplied.

digestModel is computed as follows (where H is the digest algorithm supplied via params.PCRAlgorithm):

digest1 = H(tpm2.HashAlgorithmSHA384 || sign-key-sha3-384 || brand-id)
digest2 = H(digest1 || model)
digestModel = H(digest2 || series || grade)

The signing key digest algorithm is encoded in little-endian format, and the sign-key-sha3-384 field is hashed in decoded (binary) form. The brand-id, model and series fields are hashed without null terminators. The grade field is encoded as the 32 bits from asserts.ModelGrade.Code in little-endian format.

Separate extend operations are used because brand-id, model and series are variable length.

The PCR index that snap-bootstrap measures the model to can be specified via the PCRIndex field of params.

The set of models to add to the PCRProtectionProfile is specified via the Models field of params.

func BlockPCRProtectionPolicies

func BlockPCRProtectionPolicies(tpm *Connection, pcrs []int) error

BlockPCRProtectionPolicies inserts a fence in to the specific PCRs for all active PCR banks, in order to make PCR policies that depend on the specified PCRs and are satisfiable by the current PCR values invalid until the next TPM restart (equivalent to eg, system resume from suspend-to-disk) or TPM reset (equivalent to booting after a system reset).

This acts as a barrier between the environment in which a sealed key should be permitted to be unsealed (eg, the initramfs), and the environment in which a sealed key should not be permitted to be unsealed (eg, the OS runtime).

func EncodeEKCertificateChain

func EncodeEKCertificateChain(ekCert *x509.Certificate, parents []*x509.Certificate, w io.Writer) error

EncodeEKCertificateChain will write the specified EK certificate and associated parent certificates to the specified io.Writer in a form that can be decoded by SecureConnectToDefaultTPM. This is useful in scenarios where the EK certificate cannot be located automatically, or the EK certificate or any intermediate certificates lack the Authority Information Access extension but the certificates have been downloaded manually by the caller.

If the EK certificate can be obtained reliably from the TPM during establishment of a connection, then it can be omitted in order to save a file that only contains parent certificates. In this case, SecureConnectToDefaultTPM will attempt to obtain the EK certificate from the TPM and verify it against the supplied parent certificates.

func FetchAndSaveEKCertificateChain

func FetchAndSaveEKCertificateChain(tpm *Connection, parentsOnly bool, destPath string) error

FetchAndSaveEKCertificateChain attempts to obtain the endorsement key certificate for the TPM associated with the tpm parameter, download the parent certificates and then save them atomically to the specified file in a form that can be decoded by SecureConnectToDefaultTPM. This function requires network access.

This depends on the presence of the Authority Information Access extension in the leaf certificate and any intermediate certificates, which must contain a URL for the parent certificate.

This function will stop when it encounters a certificate that doesn't specify an issuer URL, or when it encounters a self-signed certificate.

If no endorsement key certificate can be obtained, an error will be returned.

If parentsOnly is true, this function will only save the parent certificates as long as the endorsement key certificate can be reliably obtained from the TPM.

func MeasureSnapModelToTPM

func MeasureSnapModelToTPM(tpm *Connection, pcrIndex int, model secboot.SnapModel) error

MeasureSnapModelToTPM measures a digest of the supplied model assertion to the specified PCR for all supported PCR banks. See the documentation for AddSnapModelProfile for details of how the digest of the model is computed.

func MeasureSnapSystemEpochToTPM

func MeasureSnapSystemEpochToTPM(tpm *Connection, pcrIndex int) error

MeasureSnapSystemEpochToTPM measures a digest of uint32(0) to the specified PCR for all supported PCR banks. See the documentation for AddSnapModelProfile for more details.

func NewFileSealedKeyObjectReader

func NewFileSealedKeyObjectReader(path string) (io.Reader, error)

NewFileSealedKeyObjectReader creates an io.Reader from the file at the specified path that can be passed to ReadSealedKeyObject. The file will have been previously created by SealKeyToTPM. If the file cannot be opened, an *os.PathError error will be returned.

This function decodes part of the metadata specific to key files. If this fails, an InvalidKeyDataError error will be returned.

func NewKeyDataFromSealedKeyObjectFile

func NewKeyDataFromSealedKeyObjectFile(path string) (*secboot.KeyData, error)

NewKeyDataFromSealedKeyObjectFile creates a secboot.KeyData for the TPM sealed key object at the supplied path, in order to enable keys to be recovered from the TPM sealed key object using the secboot.KeyData API.

Note that the returned KeyData does not support the snap model authorization API, and consumers of this function should not attempt to use this API.

If the file cannot be opened, an *os.PathError error will be returned.

This function decodes enough metadata to construct the KeyData object If this fails, an InvalidKeyDataError error will be returned.

func RequestTPMClearUsingPPI

func RequestTPMClearUsingPPI() error

RequestTPMClearUsingPPI submits a request to the firmware to clear the TPM on the next reboot. This is the only way to clear the TPM if owner clear has been disabled for the TPM, or the lockout hierarchy authorization value has been set previously but is unknown.

func SaveEKCertificateChain

func SaveEKCertificateChain(ekCert *x509.Certificate, parents []*x509.Certificate, destPath string) error

SaveEKCertificateChain will save the specified EK certificate and associated parent certificates atomically to the specified file in a form that can be decoded by SecureConnectToDefaultTPM. This is useful in scenarios where the EK certificate cannot be located automatically, or the EK certificate or any intermediate certificates lack the Authority Information Access extension but the certificates have been downloaded manually by the caller.

If the EK certificate can be obtained reliably from the TPM during establishment of a connection, then it can be omitted in order to save a file that only contains parent certificates. In this case, SecureConnectToDefaultTPM will attempt to obtain the EK certificate from the TPM and verify it against the supplied parent certificates.

func UpdateKeyPCRProtectionPolicyMultiple

func UpdateKeyPCRProtectionPolicyMultiple(tpm *Connection, keys []*SealedKeyObject, authKey PolicyAuthKey, pcrProfile *PCRProtectionProfile) error

UpdateKeyPCRProtectionPolicyMultiple updates the PCR protection policy for the supplied sealed key objects to the profile defined by the pcrProfile argument. The keys must all be related (ie, they were created using SealKeyToTPMMultiple). If any key in the supplied set is not related, an error will be returned.

If validation of any sealed key object fails, a InvalidKeyDataError error will be returned.

On success, each of the supplied SealedKeyObjects will have an updated authorization policy that includes a PCR policy computed from the supplied PCRProtectionProfile. They must be persisted using SealedKeyObject.WriteAtomic.

Types

type AuthFailError

type AuthFailError struct {
	Handle tpm2.Handle
}

AuthFailError is returned when an authorization check fails. The provided handle indicates the resource for which authorization failed. Whilst the error normally indicates that the provided authorization value is incorrect, it may also be returned for other reasons that would cause a HMAC check failure, such as a communication failure between the host CPU and the TPM or the name of a resource on the TPM not matching the name of the ResourceContext passed to the function that failed - this latter issue can occur when using a resource manager if another process accesses the TPM and makes changes to persistent resources or sessions.

func (AuthFailError) Error

func (e AuthFailError) Error() string

type Connection

type Connection struct {
	*tpm2.TPMContext
	// contains filtered or unexported fields
}

Connection corresponds to a connection to a TPM device, and is a wrapper around *tpm2.TPMContext.

func ConnectToDefaultTPM

func ConnectToDefaultTPM() (*Connection, error)

ConnectToDefaultTPM will attempt to connect to the default TPM. It makes no attempt to verify the authenticity of the TPM. This function is useful for connecting to a device that isn't correctly provisioned and for which the endorsement hierarchy authorization value is unknown (so that it can be cleared), or for connecting to a device in order to execute FetchAndSaveEKCertificateChain. It should not be used in any other scenario.

If no TPM2 device is available, then a ErrNoTPM2Device error will be returned.

func SecureConnectToDefaultTPM

func SecureConnectToDefaultTPM(ekCertDataReader io.Reader, endorsementAuth []byte) (*Connection, error)

SecureConnectToDefaultTPM will attempt to connect to the default TPM, verify the manufacturer issued endorsement key certificate against the built-in CA roots and then verify that the TPM is the one for which the endorsement certificate was issued.

The ekCertDataReader argument should read from a file or buffer created previously by FetchAndSaveEKCertificateChain, SaveEKCertificateChain or EncodeEKCertificateChain. An error will be returned if this is not provided.

If the data read from ekCertDataReader cannot be unmarshalled or parsed correctly, a EKCertVerificationError error will be returned.

If ekCertDataReader does not contain an endorsement key certificate, this function will attempt to obtain the certificate for the TPM. This does not require network access. If this fails, a EKCertVerificationError error will be returned.

If verification of the endorsement key certificate fails, a EKCertVerificationError error will be returned. This might mean that the data provided via ekCertDataReader is invalid and needs to be recreated.

In order for the TPM to prove it is the device for which the endorsement key certificate was issued, an endorsement key is required. If the TPM doesn't contain a valid persistent endorsement key at the expected location (eg, if ProvisionTPM hasn't been executed yet), this function will attempt to create a transient endorsement key. This requires knowledge of the endorsement hierarchy authorization value, provided via the endorsementAuth argument, The endorsement hierarchy authorization value will be empty on a newly cleared device. If there is no valid persistent endorsement key and creation of a transient endorsement key fails, ErrTPMProvisioning will be returned. Note that creation of a transient endorsement key may take a long time on some TPMs (in excess of 10 seconds).

If the TPM cannot prove it is the device for which the endorsement key certificate was issued, a TPMVerificationError error will be returned. This can happen if there is an object at the persistent endorsement key index but it is not the object for which the endorsement key certificate was issued, and creation of a transient endorsement key fails because the correct endorsement hierarchy authorization value hasn't been provided via the endorsementAuth argument.

If no TPM2 device is available, then a ErrNoTPM2Device error will be returned.

func (*Connection) Close

func (t *Connection) Close() error

func (*Connection) EndorsementKey

func (t *Connection) EndorsementKey() (tpm2.ResourceContext, error)

EndorsementKey returns a reference to the TPM's persistent endorsement key, if one exists. If the endorsement key certificate has been verified, the returned ResourceContext will correspond to the object for which the certificate was issued and can safely be used to share secrets with the TPM.

func (*Connection) EnsureProvisioned

func (t *Connection) EnsureProvisioned(mode ProvisionMode, newLockoutAuth []byte) error

EnsureProvisioned prepares the TPM for full disk encryption. The mode parameter specifies the behaviour of this function.

If mode is ProvisionModeClear, this function will attempt to clear the TPM before provisioning it. If owner clear has been disabled (which will be the case if the TPM has previously been provisioned with this function), then ErrTPMClearRequiresPPI will be returned. In this case, the TPM must be cleared via the physical presence interface by calling RequestTPMClearUsingPPI and performing a system restart. Note that clearing the TPM makes all previously sealed keys permanently unrecoverable. This mode should normally be used when resetting a device to factory settings (ie, performing a new installation).

If mode is ProvisionModeClear or ProvisionModeFull, then the authorization value for the lockout hierarchy will be set to newLockoutAuth, owner clear will be disabled, and the parameters of the TPM's dictionary attack logic will be configured to appropriate values.

If mode is ProvisionModeClear or ProvisionModeFull, this function performs operations that require the use of the lockout hierarchy (detailed above), and knowledge of the lockout hierarchy's authorization value. This must be provided by calling Connection.LockoutHandleContext().SetAuthValue() prior to this call. If the wrong lockout hierarchy authorization value is provided, then a AuthFailError error will be returned. If this happens, the TPM will have entered dictionary attack lockout mode for the lockout hierarchy. Further calls will result in a ErrTPMLockout error being returned. The only way to recover from this is to either wait for the pre-programmed recovery time to expire, or to clear the TPM via the physical presence interface by calling RequestTPMClearUsingPPI. If the lockout hierarchy authorization value is not known then mode should be set to ProvisionModeWithoutLockout, with the caveat that this mode cannot fully provision the TPM.

If mode is ProvisionModeFull or ProvisionModeWithoutLockout, this function will not affect the ability to recover sealed keys that can currently be recovered.

In all modes, this function will create and persist both a storage root key and an endorsement key. Both of these will be persisted at the handles specied in the "TCG TPM v2.0 Provisioning Guidance" specification. The endorsement key will be created using the RSA template defined in the "TCG EK Credential Profile for TPM Family 2.0" specification. The storage root key will be created using the RSA template defined in the "TCG TPM v2.0 Provisioning Guidance" specification unless the TPM has previously been provisioned with a custom SRK template using the EnsureProvisionedWithCustomSRK function and mode is not ProvisionModeClear, in which case, the originally supplied template will be used instead. If there are any objects already stored at the locations required for either primary key, then this function will evict them automatically from the TPM. These operations both require the use of the storage and endorsement hierarchies. If mode is ProvisionModeFull or ProvisionModeWithoutLockout, then knowledge of the authorization values for these hierarchies is required. Whilst these will be empty after clearing the TPM, if they have been set since clearing the TPM then they will need to be provided by calling Connection.EndorsementHandleContext().SetAuthValue() and Connection.OwnerHandleContext().SetAuthValue() prior to calling this function. If the wrong value is provided for either authorization, then a AuthFailError error will be returned. If the correct authorization values are not known, then the only way to recover from this is to clear the TPM either by calling this function with mode set to ProvisionModeClear (and providing the correct authorization value for the lockout hierarchy), or by using the physical presence interface.

If mode is ProvisionModeWithoutLockout but the TPM indicates that use of the lockout hierarchy is required to fully provision the TPM (eg, to disable owner clear, set the lockout hierarchy authorization value or configure the DA lockout parameters), then a ErrTPMProvisioningRequiresLockout error will be returned. In this scenario, the function will complete all operations that can be completed without using the lockout hierarchy, but the function should be called again either with mode set to ProvisionModeFull (if the authorization value for the lockout hierarchy is known), or ProvisionModeClear.

func (*Connection) EnsureProvisionedWithCustomSRK

func (t *Connection) EnsureProvisionedWithCustomSRK(mode ProvisionMode, newLockoutAuth []byte, srkTemplate *tpm2.Public) error

EnsureProvisionedWithCustomSRK prepares the TPM for full disk encryption. The mode parameter specifies the behaviour of this function.

EnsureProvisioned is generally preferred over this function.

If mode is ProvisionModeClear, this function will attempt to clear the TPM before provisioning it. If owner clear has been disabled (which will be the case if the TPM has previously been provisioned with this function), then ErrTPMClearRequiresPPI will be returned. In this case, the TPM must be cleared via the physical presence interface by calling RequestTPMClearUsingPPI and performing a system restart. Note that clearing the TPM makes all previously sealed keys permanently unrecoverable. This mode should normally be used when resetting a device to factory settings (ie, performing a new installation).

If mode is ProvisionModeClear or ProvisionModeFull, then the authorization value for the lockout hierarchy will be set to newLockoutAuth, owner clear will be disabled, and the parameters of the TPM's dictionary attack logic will be configured to appropriate values.

If mode is ProvisionModeClear or ProvisionModeFull, this function performs operations that require the use of the lockout hierarchy (detailed above), and knowledge of the lockout hierarchy's authorization value. This must be provided by calling Connection.LockoutHandleContext().SetAuthValue() prior to this call. If the wrong lockout hierarchy authorization value is provided, then a AuthFailError error will be returned. If this happens, the TPM will have entered dictionary attack lockout mode for the lockout hierarchy. Further calls will result in a ErrTPMLockout error being returned. The only way to recover from this is to either wait for the pre-programmed recovery time to expire, or to clear the TPM via the physical presence interface by calling RequestTPMClearUsingPPI. If the lockout hierarchy authorization value is not known then mode should be set to ProvisionModeWithoutLockout, with the caveat that this mode cannot fully provision the TPM.

If mode is ProvisionModeFull or ProvisionModeWithoutLockout, this function will not affect the ability to recover sealed keys that can currently be recovered.

In all modes, this function will create and persist both a storage root key and an endorsement key. Both of these will be persisted at the handles specied in the "TCG TPM v2.0 Provisioning Guidance" specification. The endorsement key will be created using the RSA template defined in the "TCG EK Credential Profile for TPM Family 2.0" specification. The storage root key will be created using the RSA template defined in the "TCG TPM v2.0 Provisioning Guidance" specification unless the srkTemplate argument is supplied, in which case, this template will be used instead. If there are any objects already stored at the locations required for either primary key, then this function will evict them automatically from the TPM. These operations both require the use of the storage and endorsement hierarchies. If mode is ProvisionModeFull or ProvisionModeWithoutLockout, then knowledge of the authorization values for these hierarchies is required. Whilst these will be empty after clearing the TPM, if they have been set since clearing the TPM then they will need to be provided by calling Connection.EndorsementHandleContext().SetAuthValue() and Connection.OwnerHandleContext().SetAuthValue() prior to calling this function. If the wrong value is provided for either authorization, then a AuthFailError error will be returned. If the correct authorization values are not known, then the only way to recover from this is to clear the TPM either by calling this function with mode set to ProvisionModeClear (and providing the correct authorization value for the lockout hierarchy), or by using the physical presence interface.

If srkTemplate is supplied, it will be persisted inside the TPM. Future calls to EnsureProvisioned will use this template unless mode is set to ProvisionModeClear. The template will also be used to recreate the storage root key during device activation if the initial unsealing fails.

If mode is ProvisionModeWithoutLockout but the TPM indicates that use of the lockout hierarchy is required to fully provision the TPM (eg, to disable owner clear, set the lockout hierarchy authorization value or configure the DA lockout parameters), then a ErrTPMProvisioningRequiresLockout error will be returned. In this scenario, the function will complete all operations that can be completed without using the lockout hierarchy, but the function should be called again either with mode set to ProvisionModeFull (if the authorization value for the lockout hierarchy is known), or ProvisionModeClear.

func (*Connection) HmacSession

func (t *Connection) HmacSession() tpm2.SessionContext

HmacSession returns a HMAC session instance which was created in order to conduct a proof-of-ownership check of the private part of the endorsement key on the TPM. It is retained in order to reduce the number of sessions that need to be created during unseal operations, and is created with a symmetric algorithm so that it is suitable for parameter encryption. If the connection was created with SecureConnectToDefaultTPM, the session is salted with a value protected by the public part of the key associated with the verified endorsement key certificate. The session key can only be retrieved by and used on the TPM for which the endorsement certificate was issued. If the connection was created with ConnectToDefaultTPM, the session may be salted with a value protected by the public part of the endorsement key if one exists or one is able to be created, but as the key is not associated with a verified credential, there is no guarantee that only the TPM is able to retrieve the session key.

func (*Connection) IsEnabled

func (t *Connection) IsEnabled() bool

IsEnabled indicates whether the TPM is enabled or whether it has been disabled by the platform firmware. A TPM device can be disabled by the platform firmware by disabling the storage and endorsement hierarchies, but still remain visible to the operating system.

func (*Connection) VerifiedDeviceAttributes

func (t *Connection) VerifiedDeviceAttributes() *DeviceAttributes

VerifiedDeviceAttributes returns the TPM device attributes for this TPM, obtained from the verified endorsement key certificate.

func (*Connection) VerifiedEKCertChain

func (t *Connection) VerifiedEKCertChain() []*x509.Certificate

VerifiedEKCertChain returns the verified certificate chain for the endorsement key certificate obtained from this TPM. It was verified using one of the built-in TPM manufacturer root CA certificates.

type DeviceAttributes

type DeviceAttributes struct {
	Manufacturer    tpm2.TPMManufacturer
	Model           string
	FirmwareVersion uint32
}

DeviceAttributes contains details about the TPM extracted from a manufacturer issued endorsement key certificate.

type EKCertVerificationError

type EKCertVerificationError struct {
	// contains filtered or unexported fields
}

EKCertVerificationError is returned from SecureConnectToDefaultTPM if verification of the EK certificate against the built-in root CA certificates fails, or the EK certificate does not have the correct properties, or the supplied certificate data cannot be unmarshalled correctly because it is invalid.

func (EKCertVerificationError) Error

func (e EKCertVerificationError) Error() string

type FileSealedKeyObjectWriter

type FileSealedKeyObjectWriter struct {
	*bytes.Buffer
	// contains filtered or unexported fields
}

func NewFileSealedKeyObjectWriter

func NewFileSealedKeyObjectWriter(path string) *FileSealedKeyObjectWriter

NewFileSealedKeyObjectWriter creates a new writer for atomically updating a sealed key data file using SealedKeyObject.WriteAtomic.

func (*FileSealedKeyObjectWriter) Commit

func (w *FileSealedKeyObjectWriter) Commit() (err error)

type InvalidKeyDataError

type InvalidKeyDataError struct {
	// contains filtered or unexported fields
}

InvalidKeyDataError indicates that the provided key data file is invalid. This error may also be returned in some scenarious where the TPM is incorrectly provisioned, but it isn't possible to determine whether the error is with the provisioning status or because the key data file is invalid.

func (InvalidKeyDataError) Error

func (e InvalidKeyDataError) Error() string

type KeyCreationParams

type KeyCreationParams struct {
	// PCRProfile defines the profile used to generate a PCR protection policy for the newly created sealed key file.
	PCRProfile *PCRProtectionProfile

	// PCRPolicyCounterHandle is the handle at which to create a NV index for PCR authorization policy revocation support. The handle
	// must either be tpm2.HandleNull (in which case, no NV index will be created and the sealed key will not benefit from PCR
	// authorization policy revocation support), or it must be a valid NV index handle (MSO == 0x01). The choice of handle should take
	// in to consideration the reserved indices from the "Registry of reserved TPM 2.0 handles and localities" specification. It is
	// recommended that the handle is in the block reserved for owner objects (0x01800000 - 0x01bfffff).
	PCRPolicyCounterHandle tpm2.Handle

	// AuthKey can be set to chose an auhorisation key whose
	// private part will be used for authorizing PCR policy
	// updates with SealedKeyObject.UpdatePCRProtectionPolicy
	// If set a key from elliptic.P256 must be used,
	// if not set one is generated.
	AuthKey *ecdsa.PrivateKey
}

KeyCreationParams provides arguments for SealKeyToTPM.

type PCRProtectionProfile

type PCRProtectionProfile struct {
	// contains filtered or unexported fields
}

PCRProtectionProfile defines the PCR profile used to protect a key sealed with SealKeyToTPM. It contains a sequence of instructions for computing combinations of PCR values that a key will be protected against. The profile is built using the methods of this type.

func NewPCRProtectionProfile

func NewPCRProtectionProfile() *PCRProtectionProfile

func (*PCRProtectionProfile) AddPCRValue

func (p *PCRProtectionProfile) AddPCRValue(alg tpm2.HashAlgorithmId, pcr int, value tpm2.Digest) *PCRProtectionProfile

AddPCRValue adds the supplied value to this profile for the specified PCR. This action replaces any value set previously in this profile. The function returns the same PCRProtectionProfile so that calls may be chained.

func (*PCRProtectionProfile) AddPCRValueFromTPM

func (p *PCRProtectionProfile) AddPCRValueFromTPM(alg tpm2.HashAlgorithmId, pcr int) *PCRProtectionProfile

AddPCRValueFromTPM adds the current value of the specified PCR to this profile. This action replaces any value set previously in this profile. The current value is read back from the TPM when the PCR values generated by this profile are computed. The function returns the same PCRProtectionProfile so that calls may be chained.

func (*PCRProtectionProfile) AddProfileOR

func (p *PCRProtectionProfile) AddProfileOR(profiles ...*PCRProtectionProfile) *PCRProtectionProfile

AddProfileOR adds one or more sub-profiles that can be used to define PCR policies for multiple conditions. Note that each branch must explicitly define values for the same set of PCRs. It is not possible to generate policies where each branch defines values for a different set of PCRs. When computing the PCR values for this profile, the sub-profiles added by this command will inherit the PCR values computed by this profile. The function returns the same PCRProtectionProfile so that calls may be chained.

func (*PCRProtectionProfile) ComputePCRDigests

func (p *PCRProtectionProfile) ComputePCRDigests(tpm *tpm2.TPMContext, alg tpm2.HashAlgorithmId) (tpm2.PCRSelectionList, tpm2.DigestList, error)

ComputePCRDigests computes a PCR selection and a list of composite PCR digests from this PCRProtectionProfile (one composite digest per complete branch). The returned list of PCR digests is de-duplicated.

func (*PCRProtectionProfile) ComputePCRValues

func (p *PCRProtectionProfile) ComputePCRValues(tpm *tpm2.TPMContext) ([]tpm2.PCRValues, error)

ComputePCRValues computes PCR values for this PCRProtectionProfile, returning one set of PCR values for each complete branch. The returned list of PCR values is not de-duplicated.

func (*PCRProtectionProfile) ExtendPCR

func (p *PCRProtectionProfile) ExtendPCR(alg tpm2.HashAlgorithmId, pcr int, value tpm2.Digest) *PCRProtectionProfile

ExtendPCR extends the value of the specified PCR in this profile with the supplied value. If this profile doesn't yet have a value for the specified PCR, an initial value of all zeroes will be added first. The function returns the same PCRProtectionProfile so that calls may be chained.

func (*PCRProtectionProfile) String

func (p *PCRProtectionProfile) String() string

type PolicyAuthKey added in v0.0.9

type PolicyAuthKey []byte

PolicyAuthKey corresponds to the private part of the key used for signing updates to the authorization policy for a sealed key.

func SealKeyToExternalTPMStorageKey

func SealKeyToExternalTPMStorageKey(tpmKey *tpm2.Public, key []byte, keyPath string, params *KeyCreationParams) (authKey PolicyAuthKey, err error)

SealKeyToExternalTPMStorageKey seals the supplied disk encryption key to the TPM storage key associated with the supplied public tpmKey. This creates an importable sealed key and is suitable in environments that don't have access to the TPM but do have access to the public part of the TPM's storage primary key. The sealed key object and associated metadata that is required during early boot in order to unseal the key again and unlock the associated encrypted volume is written to a file at the path specified by keyPath.

The tpmKey argument must correspond to the storage primary key on the target TPM, persisted at the standard handle.

This function cannot create a sealed key that uses a PCR policy counter. The PCRPolicyCounterHandle field of the params argument must be tpm2.HandleNull.

The key will be protected with a PCR policy computed from the PCRProtectionProfile supplied via the PCRProfile field of the params argument.

On success, this function returns the private part of the key used for authorizing PCR policy updates with UpdateKeyPCRProtectionPolicy. This key doesn't need to be stored anywhere, and certainly mustn't be stored outside of the encrypted volume protected with this sealed key file. The key is stored encrypted inside this sealed key file and returned from future calls to SealedKeyObject.UnsealFromTPM.

The authorization key can also be chosen and provided by setting AuthKey in the params argument.

func SealKeyToTPM

func SealKeyToTPM(tpm *Connection, key []byte, keyPath string, params *KeyCreationParams) (authKey PolicyAuthKey, err error)

SealKeyToTPM seals the supplied disk encryption key to the storage hierarchy of the TPM. The sealed key object and associated metadata that is required during early boot in order to unseal the key again and unlock the associated encrypted volume is written to a file at the path specified by keyPath.

This function requires knowledge of the authorization value for the storage hierarchy, which must be provided by calling Connection.OwnerHandleContext().SetAuthValue() prior to calling this function. If the provided authorization value is incorrect, a AuthFailError error will be returned.

If the TPM is not correctly provisioned, a ErrTPMProvisioning error will be returned. In this case, ProvisionTPM must be called before proceeding.

This function will create a NV index at the handle specified by the PCRPolicyCounterHandle field of the params argument if it is not tpm2.HandleNull. If the handle is already in use, a TPMResourceExistsError error will be returned. In this case, the caller will need to either choose a different handle or undefine the existing one. If it is not tpm2.HandleNull, then it must be a valid NV index handle (MSO == 0x01), and the choice of handle should take in to consideration the reserved indices from the "Registry of reserved TPM 2.0 handles and localities" specification. It is recommended that the handle is in the block reserved for owner objects (0x01800000 - 0x01bfffff).

The key will be protected with a PCR policy computed from the PCRProtectionProfile supplied via the PCRProfile field of the params argument.

On success, this function returns the private part of the key used for authorizing PCR policy updates with UpdateKeyPCRProtectionPolicy. This key doesn't need to be stored anywhere, and certainly mustn't be stored outside of the encrypted volume protected with this sealed key file. The key is stored encrypted inside this sealed key file and returned from future calls to SealedKeyObject.UnsealFromTPM.

The authorization key can also be chosen and provided by setting AuthKey in the params argument.

func SealKeyToTPMMultiple

func SealKeyToTPMMultiple(tpm *Connection, keys []*SealKeyRequest, params *KeyCreationParams) (authKey PolicyAuthKey, err error)

SealKeyToTPMMultiple seals the supplied disk encryption keys to the storage hierarchy of the TPM. The keys are specified by the keys argument, which is a slice of associated key and corresponding file path. The sealed key objects and associated metadata that is required during early boot in order to unseal the keys again and unlock the associated encrypted volumes are written to files at the specifed paths.

This function requires knowledge of the authorization value for the storage hierarchy, which must be provided by calling Connection.OwnerHandleContext().SetAuthValue() prior to calling this function. If the provided authorization value is incorrect, a AuthFailError error will be returned.

This function will create a NV index at the handle specified by the PCRPolicyCounterHandle field of the params argument if it is not tpm2.HandleNull. If the handle is already in use, a TPMResourceExistsError error will be returned. In this case, the caller will need to either choose a different handle or undefine the existing one. If it is not tpm2.HandleNull, then it must be a valid NV index handle (MSO == 0x01), and the choice of handle should take in to consideration the reserved indices from the "Registry of reserved TPM 2.0 handles and localities" specification. It is recommended that the handle is in the block reserved for owner objects (0x01800000 - 0x01bfffff).

All keys will be created with the same authorization policy, and will be protected with a PCR policy computed from the PCRProtectionProfile supplied via the PCRProfile field of the params argument.

If any part of this function fails, no sealed keys will be created.

On success, this function returns the private part of the key used for authorizing PCR policy updates with UpdateKeyPCRProtectionPolicyMultiple. This key doesn't need to be stored anywhere, and certainly mustn't be stored outside of the encrypted volume protected with this sealed key file. The key is stored encrypted inside this sealed key file and returned from future calls to SealedKeyObject.UnsealFromTPM.

The authorization key can also be chosen and provided by setting AuthKey in the params argument.

type ProvisionMode

type ProvisionMode int

ProvisionMode is used to control the behaviour of Connection.EnsureProvisioned.

const (
	// ProvisionModeWithoutLockout specifies that the TPM should be refreshed without performing operations that require the use of the
	// lockout hierarchy. Operations that won't be performed in this mode are disabling owner clear, configuring the dictionary attack
	// parameters, and setting the authorization value for the lockout hierarchy.
	ProvisionModeWithoutLockout ProvisionMode = iota

	// ProvisionModeFull specifies that the TPM should be fully provisioned without clearing it. This requires use of the lockout
	// hierarchy.
	ProvisionModeFull

	// ProvisionModeClear specifies that the TPM should be fully provisioned after clearing it. This requires use of the lockout
	// hierarchy.
	ProvisionModeClear
)

type SealKeyRequest

type SealKeyRequest struct {
	Key  []byte
	Path string
}

SealKeyRequest corresponds to a key that should be sealed by SealKeyToTPMMultiple to a file at the specified path.

type SealedKeyObject

type SealedKeyObject struct {
	// contains filtered or unexported fields
}

SealedKeyObject corresponds to a sealed key data file.

func ReadSealedKeyObject

func ReadSealedKeyObject(r io.Reader) (*SealedKeyObject, error)

ReadSealedKeyObject reads a SealedKeyObject from the supplied io.Reader. If it cannot be correctly decoded, an InvalidKeyDataError error will be returned.

func ReadSealedKeyObjectFromFile

func ReadSealedKeyObjectFromFile(path string) (*SealedKeyObject, error)

ReadSealedKeyObjectFromFile reads a SealedKeyObject from the file created by SealKeyToTPM at the specified path. If the file cannot be opened, an *os.PathError error is returned. If the file cannot be deserialized successfully, an InvalidKeyDataError error will be returned.

func (*SealedKeyObject) PCRPolicyCounterHandle

func (k *SealedKeyObject) PCRPolicyCounterHandle() tpm2.Handle

PCRPolicyCounterHandle indicates the handle of the NV counter used for PCR policy revocation for this sealed key object (and for PIN integration for version 0 key files).

func (*SealedKeyObject) RevokeOldPCRProtectionPolicies

func (k *SealedKeyObject) RevokeOldPCRProtectionPolicies(tpm *Connection, authKey PolicyAuthKey) error

RevokeOldPCRProtectionPolicies revokes old PCR protection policies associated with this sealed key. It does this by incrementing the PCR policy counter associated with this sealed key on the TPM so that it contains the value of the current PCR policy sequence number. PCR policies with a lower sequence number cannot be satisfied and become invalid. The PCR policy sequence number is incremented on each call to UpdatePCRProtectionPolicy. If the key data was not created with a PCR policy counter, then this function does nothing.

The caller must also specify the private part of the authorization key that was either returned by SealKeyToTPM or SealedKeyObject.UnsealFromTPM.

Note that this will perform a NV write for each call to UpdatePCRProtectionPolicy since the last call to RevokeOldPCRProtectionPolicies. As TPMs may apply rate-limiting to NV writes, this should be called after each call to UpdatePCRProtectionPolicy that removes some PCR policy branches.

If validation of the key data fails, a InvalidKeyDataError error will be returned.

func (*SealedKeyObject) RevokeOldPCRProtectionPoliciesV0

func (k *SealedKeyObject) RevokeOldPCRProtectionPoliciesV0(tpm *Connection, policyUpdatePath string) error

RevokeOldPCRProtectionPoliciesV0 revokes old PCR protection policies associated with this sealed key. It does this by incrementing the PCR policy counter associated with this sealed key on the TPM so that it contains the value of the current PCR policy sequence number. PCR policies with a lower sequence number cannot be satisfied and become invalid. The PCR policy sequence number is incremented on each call to UpdatePCRProtectionPolicyV0.

This function only works with version 0 sealed key data objects. The caller must specify the path to the policy update data file that was originally saved by SealKeyToTPM.

Note that this will perform a NV write for each call to UpdatePCRProtectionPolicyV0 since the last call to RevokeOldPCRProtectionPoliciesV0. As TPMs may apply rate-limiting to NV writes, this should be called after each call to UpdatePCRProtectionPolicyV0 that removes some PCR policy branches.

If validation of the key data fails, a InvalidKeyDataError error will be returned.

func (*SealedKeyObject) UnsealFromTPM

func (k *SealedKeyObject) UnsealFromTPM(tpm *Connection) (key []byte, authKey PolicyAuthKey, err error)

UnsealFromTPM will load the TPM sealed object in to the TPM and attempt to unseal it, returning the cleartext key on success.

If the TPM's dictionary attack logic has been triggered, a ErrTPMLockout error will be returned.

If the TPM is not provisioned correctly, then a ErrTPMProvisioning error will be returned. In this case, ProvisionTPM should be called to attempt to resolve this.

If the TPM sealed object cannot be loaded in to the TPM for reasons other than the lack of a storage root key, then a InvalidKeyDataError error will be returned. This could be caused because the sealed object data is invalid in some way, or because the sealed object is associated with another TPM owner (the TPM has been cleared since the sealed key data file was created with SealKeyToTPM), or because the TPM object at the persistent handle reserved for the storage root key has a public area that looks like a valid storage root key but it was created with the wrong template. This latter case is really caused by an incorrectly provisioned TPM, but it isn't possible to detect this. A subsequent call to SealKeyToTPM or ProvisionTPM will rectify this.

If the TPM's current PCR values are not consistent with the PCR protection policy for this key file, a InvalidKeyDataError error will be returned.

If any of the metadata in this key file is invalid, a InvalidKeyDataError error will be returned.

If the TPM is missing any persistent resources associated with this key file, then a InvalidKeyDataError error will be returned.

If the key file has been superceded (eg, by a call to SealedKeyObject.UpdatePCRProtectionPolicy), then a InvalidKeyDataError error will be returned.

If the signature of the updatable part of the key file's authorization policy is invalid, then a InvalidKeyDataError error will be returned.

If the metadata for the updatable part of the key file's authorization policy is not consistent with the approved policy, then a InvalidKeyDataError error will be returned.

If the authorization policy check fails during unsealing, then a InvalidKeyDataError error will be returned. Note that this condition can also occur as the result of an incorrectly provisioned TPM, which will be detected during a subsequent call to SealKeyToTPM.

On success, the unsealed cleartext key is returned as the first return value, and the private part of the key used for authorizing PCR policy updates with UpdateKeyPCRProtectionPolicy is returned as the second return value.

func (*SealedKeyObject) UpdatePCRProtectionPolicy

func (k *SealedKeyObject) UpdatePCRProtectionPolicy(tpm *Connection, authKey PolicyAuthKey, pcrProfile *PCRProtectionProfile) error

UpdatePCRProtectionPolicy updates the PCR protection policy for this sealed key object to the profile defined by the pcrProfile argument. In order to do this, the caller must also specify the private part of the authorization key that was either returned by SealKeyToTPM or SealedKeyObject.UnsealFromTPM.

If the sealed key was created with a PCR policy counter, then the sequence number of the new PCR policy will be incremented by 1 compared with the value associated with the current PCR policy. This does not increment the NV counter on the TPM - this can be done with a subsequent call to RevokeOldPCRProtectionPolicies.

On success, this SealedKeyObject will have an updated authorization policy that includes a PCR policy computed from the supplied PCRProtectionProfile. It must be persisted using SealedKeyObject.WriteAtomic.

func (*SealedKeyObject) UpdatePCRProtectionPolicyV0

func (k *SealedKeyObject) UpdatePCRProtectionPolicyV0(tpm *Connection, policyUpdatePath string, pcrProfile *PCRProtectionProfile) error

If the policy update data file cannot be opened, a wrapped *os.PathError error will be returned.

If validation of the sealed key data fails, a InvalidKeyDataError error will be returned.

On success, this SealedKeyObject will have an updated authorization policy that includes a PCR policy computed from the supplied PCRProtectionProfile. It must be persisted using SealedKeyObject.WriteAtomic.

func (*SealedKeyObject) Version

func (k *SealedKeyObject) Version() uint32

Version returns the version number that this sealed key object was created with.

func (*SealedKeyObject) WriteAtomic

func (k *SealedKeyObject) WriteAtomic(w secboot.KeyDataWriter) error

WriteAtomic will serialize this SealedKeyObject to the supplied writer.

type SnapModelProfileParams

type SnapModelProfileParams struct {
	// PCRAlgorithm is the algorithm for which to compute PCR digests for. TPMs compliant with the "TCG PC Client Platform TPM Profile
	// (PTP) Specification" Level 00, Revision 01.03 v22, May 22 2017 are required to support tpm2.HashAlgorithmSHA1 and
	// tpm2.HashAlgorithmSHA256. Support for other digest algorithms is optional.
	PCRAlgorithm tpm2.HashAlgorithmId

	// PCRIndex is the PCR that snap-bootstrap measures the model to.
	PCRIndex int

	// Models is the set of models to add to the PCR profile.
	Models []secboot.SnapModel
}

SnapModelProfileParams provides the parameters to AddSnapModelProfile.

type TPMResourceExistsError

type TPMResourceExistsError struct {
	Handle tpm2.Handle
}

TPMResourceExistsError is returned from any function that creates a persistent TPM resource if a resource already exists at the specified handle.

func (TPMResourceExistsError) Error

func (e TPMResourceExistsError) Error() string

type TPMVerificationError

type TPMVerificationError struct {
	// contains filtered or unexported fields
}

TPMVerificationError is returned from SecureConnectToDefaultTPM if the TPM cannot prove it is the device for which the verified EK certificate was issued.

func (TPMVerificationError) Error

func (e TPMVerificationError) Error() string

Jump to

Keyboard shortcuts

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