secboot

package
v0.0.0-...-4926a21 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2025 License: GPL-3.0 Imports: 37 Imported by: 69

Documentation

Index

Constants

View Source
const (
	// The range 0x01880005-0x0188000F
	//
	// TODO:FDEM: we should apply for a subrange from UAPI group once
	// they got a range assigned by TCG.  See
	// https://github.com/uapi-group/specifications/pull/118
	// For now we use a sub range on the unassigned owner handles
	PCRPolicyCounterHandleStart = uint32(0x01880005)
	PCRPolicyCounterHandleRange = uint32(0x01880010 - 0x01880005)

	// These handles are legacy, do not use them in new code.
	//
	// Handles are in the block reserved for TPM owner objects (0x01800000 - 0x01bfffff).
	//
	// Handles are rotated during factory reset, depending on the PCR handle
	// thet was used when sealing key objects during installation (or a
	// previous factory reset).
	RunObjectPCRPolicyCounterHandle         = uint32(0x01880001)
	FallbackObjectPCRPolicyCounterHandle    = uint32(0x01880002)
	AltRunObjectPCRPolicyCounterHandle      = uint32(0x01880003)
	AltFallbackObjectPCRPolicyCounterHandle = uint32(0x01880004)
)

Variables

View Source
var CreateBootstrappedContainer = createBootstrappedContainerMockImpl
View Source
var ErrKernelKeyNotFound = errors.New("kernel key not found")
View Source
var WithSecbootSupport = false

WithSecbootSupport is true if this package was built with githbu.com/snapcore/secboot.

Functions

func ActivateVolumeWithKey

func ActivateVolumeWithKey(volumeName, sourceDevicePath string, key []byte, options *ActivateVolumeOptions) error

ActivateVolumeWithKey is a wrapper for secboot.ActivateVolumeWithKey

func AddBootstrapKeyOnExistingDisk

func AddBootstrapKeyOnExistingDisk(node string, newKey keys.EncryptionKey) error

AddBootstrapKeyOnExistingDisk will add a new bootstrap key to on an existing encrypted disk. The disk is expected to be unlocked and they key is available on the keyring. The bootstrap key is temporary and is expected to be used with a BootstrappedContainer, and removed by calling RemoveBootstrapKey.

func AddRecoveryKey

func AddRecoveryKey(key keys.EncryptionKey, rkey keys.RecoveryKey, node string) error

AddRecoveryKey adds a fallback recovery key rkey to the existing encrypted volume created with FormatEncryptedDevice on the block device given by node. The existing key to the encrypted volume is provided in the key argument.

func CheckTPMKeySealingSupported

func CheckTPMKeySealingSupported(mode TPMProvisionMode) error

func DeactivateVolume

func DeactivateVolume(volumeName string) error

DeactivateVolume is a wrapper for secboot.DeactivateVolume

func DeleteKeys

func DeleteKeys(node string, matches map[string]bool) error

DeleteKeys delete key slots on a LUKS2 container. Slots that do not exist are ignored.

func DeleteOldKeys

func DeleteOldKeys(devicePath string) error

DeleteOldKeys removes key slots from an old installation that had names created by TemporaryNameOldKeys.

func EncryptedPartitionName

func EncryptedPartitionName(name string) string

EncryptedPartitionName returns the name/label used by an encrypted partition corresponding to a given name.

func EnsureRecoveryKey

func EnsureRecoveryKey(keyFile string, rkeyDevs []RecoveryKeyDevice) (keys.RecoveryKey, error)

EnsureRecoveryKey makes sure the encrypted block devices have a recovery key. It takes the path where to store the key and encrypted devices to operate on.

func FindFreeHandle

func FindFreeHandle() (uint32, error)

FindFreeHandle finds and unused handle on the TPM. The handle will be arbitrary in range 0x01880005-0x0188000F.

func FormatEncryptedDevice

func FormatEncryptedDevice(key []byte, encType device.EncryptionType, label, node string) error

FormatEncryptedDevice initializes an encrypted volume on the block device given by node, setting the specified label. The key used to unlock the volume is provided using the key argument.

func GetPCRHandle

func GetPCRHandle(node, keySlot, keyFile string) (uint32, error)

GetPCRHandle returns the handle used by a key. The key will be searched on the token of the keySlot from the node. If that keySlot has no KeyData, then the key will be loaded at path keyFile.

func GetPrimaryKeyDigest

func GetPrimaryKeyDigest(devicePath string, alg crypto.Hash) (salt []byte, digest []byte, err error)

GetPrimaryKeyDigest retrieve the primary key for a disk from the keyring and returns its digest. If the path given does not match the keyring, then it will look for symlink in /dev/disk/by-partuuid for that device.

func HijackAndRunArgon2OutOfProcessHandlerOnArg

func HijackAndRunArgon2OutOfProcessHandlerOnArg(args []string)

HijackAndRunArgon2OutOfProcessHandlerOnArg is supposed to be called from the main() of binaries involved with sealing/unsealing of keys (i.e. snapd and snap-bootstrap).

This switches the binary to a special argon2 mode when the matching args are detected where it hijacks the process and acts as an argon2 out-of-process helper command and exits when its work is done, otherwise (in normal mode) it sets the default argon2 kdf implementation to be self-invoking into the special argon2 mode of the calling binary.

For more context, check docs for sb.WaitForAndRunArgon2OutOfProcessRequest and sb.NewOutOfProcessArgon2KDF for details on how the flow works in secboot.

func LockSealedKeys

func LockSealedKeys() error

LockSealedKeys manually locks access to the sealed keys. Meant to be called in place of passing lockKeysOnFinish as true to UnlockVolumeUsingSealedKeyIfEncrypted for cases where we don't know if a given call is the last one to unlock a volume like in degraded recover mode.

func MarkSuccessful

func MarkSuccessful() error

MarkSuccessful marks the secure boot parts of the boot as successful.

This means that the dictionary attack (DA) lockout counter is reset.

func MeasureSnapModelWhenPossible

func MeasureSnapModelWhenPossible(findModel func() (*asserts.Model, error)) error

MeasureSnapModelWhenPossible measures the snap model only if the TPM device is available. If there's no TPM device success is returned.

func MeasureSnapSystemEpochWhenPossible

func MeasureSnapSystemEpochWhenPossible() error

MeasureSnapSystemEpochWhenPossible measures the snap system epoch only if the TPM device is available. If there's no TPM device success is returned.

func MockCreateBootstrappedContainer

func MockCreateBootstrappedContainer(f func(key DiskUnlockKey, devicePath string) BootstrappedContainer) func()

func ProvisionForCVM

func ProvisionForCVM(initramfsUbuntuSeedDir string) error

ProvisionForCVM provisions the default TPM using a custom SRK template that is created by the encrypt tool prior to first boot of Azure CVM instances. It takes UbuntuSeedDir (ESP) and expects "tpm2-srk.tmpl" there which is deleted after successful provision.

Key differences with ProvisionTPM() - lack of TPM or if TPM is disabled is ignored. - it is fatal if TPM Provisioning requires a Lockout file - Custom SRK file is required in InitramfsUbuntuSeedDir

func ProvisionTPM

func ProvisionTPM(mode TPMProvisionMode, lockoutAuthFile string) error

ProvisionTPM provisions the default TPM and saves the lockout authorization key to the specified file.

func RemoveOldCounterHandles

func RemoveOldCounterHandles(device string, possibleOldKeys map[string]bool, possibleKeyFiles []string, hintExpectFDEHook bool) error

RemoveOldCounterHandles releases TPM2 handles used by some keys. The keys for which handles are released are:

  • in the keyslots of the given device, with names matching possibleOldKeys.
  • in key files at paths given by possibleKeyFiles.

All TPM2 handles found in any key found will be removed. If keyslots or key files are not found, they are just ignored. hintExpectFDEHook helps reading old key object files. If not TPM2 key is found, nothing happens.

func RemoveRecoveryKeys

func RemoveRecoveryKeys(rkeyDevToKey map[RecoveryKeyDevice]string) error

RemoveRecoveryKeys removes any recovery key from all encrypted block devices. It takes a map from the recovery key device to where their recovery key is stored, mount points might share the latter.

func RenameKeys

func RenameKeys(node string, renames map[string]string) error

Rename key slots on LUKS2 container. If the key slot does not exist, it is ignored. If cryptsetup does not support renaming, then the key slots are instead removed. WARNING: this function is not always atomic. If cryptsetup is too old, it will try to copy and delete keys instead. Please avoid using this function in new code.

func ResealKeys

func ResealKeys(params *ResealKeysParams) error

ResealKeys updates the PCR protection policy for the sealed encryption keys according to the specified parameters.

func ResealKeysWithFDESetupHook

func ResealKeysWithFDESetupHook(keys []KeyDataLocation, primaryKeyFile string, models []ModelForSealing) error

ResealKeysWithFDESetupHook updates hook based keydatas for given files with a specific list of models

func SealKeys

func SealKeys(keys []SealKeyRequest, params *SealKeysParams) ([]byte, error)

SealKeys seals the encryption keys according to the specified parameters. The TPM must have already been provisioned. If sealed key already exists at the PCR handle, SealKeys will fail and return an error.

func SealKeysWithFDESetupHook

func SealKeysWithFDESetupHook(runHook fde.RunSetupHookFunc, keys []SealKeyRequest, params *SealKeysWithFDESetupHookParams) error

func StageEncryptionKeyChange

func StageEncryptionKeyChange(node string, key keys.EncryptionKey) error

StageEncryptionKeyChange stages a new encryption key for a given encrypted device. The new key is added into a temporary slot. To complete the encryption key change process, a call to TransitionEncryptionKeyChange is needed.

func TemporaryNameOldKeys

func TemporaryNameOldKeys(devicePath string) error

TemporaryNameOldKeys takes a disk using legacy keyslots 0, 1, 2 and adds names to those keyslots. This is needed to convert the save disk during a factory reset. This is a no-operation if all keyslots are already named.

func TransitionEncryptionKeyChange

func TransitionEncryptionKeyChange(mountpoint string, key keys.EncryptionKey) error

TransitionEncryptionKeyChange transitions the encryption key on an encrypted device corresponding to the given mount point. The change is authorized using the new key, thus a prior call to StageEncryptionKeyChange must be done.

func VerifyPrimaryKeyDigest

func VerifyPrimaryKeyDigest(devicePath string, alg crypto.Hash, salt []byte, digest []byte) (bool, error)

VerifyPrimaryKeyDigest retrieve the primary key for a disk from the keyring and verifies its digest. If the path given does not match the keyring, then it will look for symlink in /dev/disk/by-partuuid for that device.

Types

type ActivateVolumeOptions

type ActivateVolumeOptions sb.ActivateVolumeOptions

type BootstrappedContainer

type BootstrappedContainer interface {
	// AddKey adds a key "newKey" to "slotName".
	AddKey(slotName string, newKey []byte) error
	// GetTokenWriter returns a keydata writer that writes to the token.
	GetTokenWriter(slotName string) (KeyDataWriter, error)
	// RemoveBootstrapKey removes the bootstrap key.
	RemoveBootstrapKey() error
}

BootstrappedContainer is an abstraction for an encrypted container along with a key that is able to enroll other keys. This key is meant to be an initial key that is removed after all required keys are enrolled, by calling RemoveBootstrapKey.

type DiskUnlockKey

type DiskUnlockKey sb.DiskUnlockKey

type HashAlg

type HashAlg = sb.HashAlg

type KeyDataLocation

type KeyDataLocation struct {
	// KeyFile is the path to the file that contains either the key data or sealed key object.
	KeyFile string
	// DevicePath is the LUKS2 device which contains a token with they key data
	DevicePath string
	// SlotName is the name of the token that contains the key data
	SlotName string
}

KeyDataLocation represents the possible places where key data might be saved.

This is used for resealing keys in key data. The resealing will be responsible of finding which one is in use. The basic strategy is if a key data is found in the token, then this will be used and the key file will be ignored.

type KeyDataWriter

type KeyDataWriter interface {
	io.Writer
	Commit() error
}

KeyDataWriter is an interface used by KeyData to write the data to persistent storage in an atomic way. The interface is compatible with identically named interface from github.com/canonical/secboot.

type LoadChain

type LoadChain struct {
	*bootloader.BootFile
	// Next is a list of alternative chains that can be loaded
	// following the boot file.
	Next []*LoadChain
}

func NewLoadChain

func NewLoadChain(bf bootloader.BootFile, next ...*LoadChain) *LoadChain

NewLoadChain returns a LoadChain corresponding to loading the given BootFile before any of the given next chains.

type MockBootstrappedContainer

type MockBootstrappedContainer struct {
	BootstrapKeyRemoved bool
	Slots               map[string][]byte
	Tokens              map[string][]byte
}

func CreateMockBootstrappedContainer

func CreateMockBootstrappedContainer() *MockBootstrappedContainer

func (*MockBootstrappedContainer) AddKey

func (m *MockBootstrappedContainer) AddKey(slotName string, newKey []byte) error

func (*MockBootstrappedContainer) GetTokenWriter

func (m *MockBootstrappedContainer) GetTokenWriter(slotName string) (KeyDataWriter, error)

func (*MockBootstrappedContainer) RemoveBootstrapKey

func (l *MockBootstrappedContainer) RemoveBootstrapKey() error

type ModelForSealing

type ModelForSealing interface {
	Series() string
	BrandID() string
	Model() string
	Classic() bool
	Grade() asserts.ModelGrade
	SignKeyID() string
}

ModelForSealing provides information about the model for use in the context of (re)sealing the encryption keys.

type RecoveryKeyDevice

type RecoveryKeyDevice struct {
	// Mountpoint of the device
	Mountpoint string
	// AuthorizingKeyFile is the path to the key to authorize the
	// operation, if empty, then it is assumed that the authorization key is
	// present in the user session keyring
	AuthorizingKeyFile string
}

type ResealKeysParams

type ResealKeysParams struct {
	// The snap model parameters
	PCRProfile SerializedPCRProfile
	// The locations to the key data
	Keys []KeyDataLocation
	// The path to the authorization policy update key file (only relevant for TPM)
	TPMPolicyAuthKeyFile string
}

type SealKeyModelParams

type SealKeyModelParams struct {
	// The snap model
	Model ModelForSealing
	// The set of EFI binary load chains for the current device
	// configuration
	EFILoadChains []*LoadChain
	// The kernel command line
	KernelCmdlines []string
	// TODO:FDEM: move this somewhere else?
	// The content of an update to EFI DBX
	EFISignatureDbxUpdate []byte
}

TODO:FDEM: rename and drop Model from the name?

type SealKeyRequest

type SealKeyRequest struct {
	// The installation key to enroll a new key slot
	BootstrappedContainer BootstrappedContainer
	// The key name; identical keys should have identical names
	KeyName string
	// The name of the slot where they key will be saved.
	SlotName string
	// The file to store the key data. If empty, the key data will
	// be saved to the token.
	KeyFile string
}

type SealKeysParams

type SealKeysParams struct {
	// The parameters we're sealing the key to
	ModelParams []*SealKeyModelParams
	// The primary key to use, nil if needs to be generated
	PrimaryKey []byte
	// The handle at which to create a NV index for dynamic authorization policy revocation support
	PCRPolicyCounterHandle uint32
	// The path to the authorization policy update key file (only relevant for TPM,
	// if empty the key will not be saved)
	TPMPolicyAuthKeyFile string
	// Optional volume authentication options
	VolumesAuth *device.VolumesAuthOptions
}

type SealKeysWithFDESetupHookParams

type SealKeysWithFDESetupHookParams struct {
	// Initial model to bind sealed keys to.
	Model ModelForSealing
	// The path to the aux key file (if empty the key will not be
	// saved)
	AuxKeyFile string
	// The primary key to use, nil if needs to be generated
	PrimaryKey []byte
}

type SerializedPCRProfile

type SerializedPCRProfile []byte

SerializedPCRProfile wraps a serialized PCR profile which is treated as an opaque binary blob outside of secboot package.

func BuildPCRProtectionProfile

func BuildPCRProtectionProfile(modelParams []*SealKeyModelParams) (SerializedPCRProfile, error)

BuildPCRProtectionProfile builds and serializes a PCR profile from a list of SealKeyModelParams.

type TPMProvisionMode

type TPMProvisionMode int
const (
	TPMProvisionNone TPMProvisionMode = iota
	// TPMProvisionFull indicates a full provisioning of the TPM
	TPMProvisionFull
	// TPMPartialReprovision indicates a partial reprovisioning of the TPM
	// which was previously already provisioned by secboot. Existing lockout
	// authorization data from TPMLockoutAuthFile will be used to authorize
	// provisioning and will get overwritten in the process.
	TPMPartialReprovision
	// TPMProvisionFullWithoutLockout indicates full provisioning
	// without using lockout authorization data, as currently used
	// by Azure CVM
	TPMProvisionFullWithoutLockout
)

type UnlockMethod

type UnlockMethod int

UnlockMethod is the method that was used to unlock a volume.

const (
	// NotUnlocked indicates that the device was either not unlocked or is not
	// an encrypted device.
	NotUnlocked UnlockMethod = iota
	// UnlockedWithSealedKey indicates that the device was unlocked with the
	// provided sealed key object.
	UnlockedWithSealedKey
	// UnlockedWithRecoveryKey indicates that the device was unlocked by the
	// user providing the recovery key at the prompt.
	UnlockedWithRecoveryKey
	// UnlockedWithKey indicates that the device was unlocked with the provided
	// key, which is not sealed.
	UnlockedWithKey
	// UnlockStatusUnknown indicates that the unlock status of the device is not clear.
	UnlockStatusUnknown
)

type UnlockResult

type UnlockResult struct {
	// FsDevice is the device with filesystem ready to mount.
	// It is the activated device if encrypted or just
	// the underlying device (same as PartDevice) if non-encrypted.
	// FsDevice can be empty when none was found.
	FsDevice string
	// PartDevice is the underlying partition device.
	// PartDevice can be empty when no device was found.
	PartDevice string
	// IsEncrypted indicates that PartDevice is encrypted.
	IsEncrypted bool
	// UnlockMethod is the method used to unlock the device. Valid values are
	// - NotUnlocked
	// - UnlockedWithRecoveryKey
	// - UnlockedWithSealedKey
	// - UnlockedWithKey
	UnlockMethod UnlockMethod
}

UnlockResult is the result of trying to unlock a volume.

func UnlockEncryptedVolumeUsingProtectorKey

func UnlockEncryptedVolumeUsingProtectorKey(disk disks.Disk, name string, key []byte) (UnlockResult, error)

UnlockEncryptedVolumeUsingProtectorKey unlocks the provided device with a given plain key. Depending on how then encrypted device was set up, the key is either used to unlock the device directly, or it is used to decrypt the encrypted unlock key stored in LUKS2 tokens in the device.

func UnlockVolumeUsingSealedKeyIfEncrypted

func UnlockVolumeUsingSealedKeyIfEncrypted(disk disks.Disk, name string, sealedEncryptionKeyFile string, opts *UnlockVolumeUsingSealedKeyOptions) (UnlockResult, error)

UnlockVolumeUsingSealedKeyIfEncrypted verifies whether an encrypted volume with the specified name exists and unlocks it using a sealed key in a file with a corresponding name. The options control activation with the recovery key will be attempted if a prior activation attempt with the sealed key fails.

Note that if the function proceeds to the point where it knows definitely whether there is an encrypted device or not, IsEncrypted on the return value will be true, even if error is non-nil. This is so that callers can be robust and try unlocking using another method for example.

type UnlockVolumeUsingSealedKeyOptions

type UnlockVolumeUsingSealedKeyOptions struct {
	// AllowRecoveryKey when true indicates activation with the recovery key
	// will be attempted if activation with the sealed key failed.
	AllowRecoveryKey bool
	// WhichModel if invoked should return the device model
	// assertion for which the disk is being unlocked.
	WhichModel func() (*asserts.Model, error)
	// BootMode is the current boot mode (i.e. snapd_recovery_mode kernel parameter)
	BootMode string
}

UnlockVolumeUsingSealedKeyOptions contains options for unlocking encrypted volumes using keys sealed to the TPM.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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