Documentation ¶
Index ¶
- Constants
- Variables
- func ActivateVolumeWithKey(volumeName, sourceDevicePath string, key []byte, ...) error
- func ActivateVolumeWithRecoveryKey(volumeName, sourceDevicePath string, keyReader io.Reader, ...) error
- func AddRecoveryKeyToLUKS2Container(devicePath string, key []byte, recoveryKey RecoveryKey, options *KDFOptions) error
- func ChangeLUKS2KeyUsingRecoveryKey(devicePath string, recoveryKey RecoveryKey, key []byte) error
- func DeactivateVolume(volumeName string) error
- func InitializeLUKS2Container(devicePath, label string, key []byte, options *InitializeLUKS2ContainerOptions) error
- func RegisterPlatformKeyDataHandler(name string, handler PlatformKeyDataHandler)
- type ActivateVolumeOptions
- type AuthMode
- type AuthRequestor
- type AuxiliaryKey
- type DiskUnlockKey
- type FileKeyDataReader
- type FileKeyDataWriter
- type InitializeLUKS2ContainerOptions
- type InvalidKeyDataError
- type KDFOptions
- type KeyCreationData
- type KeyData
- func (d *KeyData) AuthMode() (out AuthMode)
- func (d *KeyData) IsSnapModelAuthorized(auxKey AuxiliaryKey, model SnapModel) (bool, error)
- func (d *KeyData) ReadableName() string
- func (d *KeyData) RecoverKeys() (DiskUnlockKey, AuxiliaryKey, error)
- func (d *KeyData) SetAuthorizedSnapModels(auxKey AuxiliaryKey, models ...SnapModel) error
- func (d *KeyData) UniqueID() (KeyID, error)
- func (d *KeyData) WriteAtomic(w KeyDataWriter) error
- type KeyDataReader
- type KeyDataWriter
- type KeyID
- type KeyPayload
- type PlatformDeviceUnavailableError
- type PlatformKeyData
- type PlatformKeyDataHandler
- type PlatformKeyRecoveryError
- type PlatformKeyRecoveryErrorType
- type PlatformUninitializedError
- type RecoveryKey
- type SnapModel
- type SnapModelChecker
Constants ¶
const ClassicModelGradeMask uint32 = 0x80000000
ClassicModelGradeMask is ORed with the model grade code when measuring a classic snap model.
Variables ¶
var ErrKernelKeyNotFound = errors.New("cannot find key in kernel keyring")
var ErrNoPlatformHandlerRegistered = errors.New("cannot recover key because there isn't a platform handler registered for it")
ErrNoPlatformHandlerRegistered is returned from any of the KeyData.RecoverKeys* functions if the keys cannot be successfully recovered because there is no appropriate platform handler registered.
var ErrRecoveryKeyUsed = errors.New("cannot activate with platform protected keys but activation with the recovery key was successful")
ErrRecoveryKeyUsed is returned from ActivateVolumeWithKeyData and ActivateVolumeWithMultipleKeyData if the volume could not be activated with any platform protected keys but activation with the recovery key was successful.
Functions ¶
func ActivateVolumeWithKey ¶
func ActivateVolumeWithKey(volumeName, sourceDevicePath string, key []byte, options *ActivateVolumeOptions) error
ActivateVolumeWithKey attempts to activate the LUKS encrypted volume at sourceDevicePath and create a mapping with the name volumeName, using the provided key. This makes use of systemd-cryptsetup.
func ActivateVolumeWithRecoveryKey ¶
func ActivateVolumeWithRecoveryKey(volumeName, sourceDevicePath string, keyReader io.Reader, options *ActivateVolumeOptions) error
ActivateVolumeWithRecoveryKey attempts to activate the LUKS encrypted volume at sourceDevicePath and create a mapping with the name volumeName, using the fallback recovery key. This makes use of systemd-cryptsetup.
This function will use systemd-ask-password to request the recovery key. If keyReader is not nil, then an attempt to read the key from this will be made instead by reading all characters until the first newline. The RecoveryKeyTries field of options defines how many attempts should be made to activate the volume with the recovery key before failing.
If the RecoveryKeyTries field of options is less than zero, an error will be returned.
func AddRecoveryKeyToLUKS2Container ¶ added in v0.0.7
func AddRecoveryKeyToLUKS2Container(devicePath string, key []byte, recoveryKey RecoveryKey, options *KDFOptions) error
AddRecoveryKeyToLUKS2Container adds a fallback recovery key to an existing LUKS2 container created with InitializeLUKS2Container. The recovery key is intended to be used as a fallback mechanism that operates independently of the TPM in order to unlock the container in the event that the key encrypted with SealKeyToTPM cannot be used to unlock it. The devicePath argument specifies the device node for the partition that contains the LUKS2 container. The existing key for the container is provided via the key argument.
The recovery key is provided via the recoveryKey argument and must be a cryptographically secure 16-byte number.
func ChangeLUKS2KeyUsingRecoveryKey ¶ added in v0.0.7
func ChangeLUKS2KeyUsingRecoveryKey(devicePath string, recoveryKey RecoveryKey, key []byte) error
ChangeLUKS2KeyUsingRecoveryKey changes the key normally used for unlocking the LUKS2 container at devicePath. This function is intended to be used after the container is unlocked with the recovery key, in the scenario that the TPM sealed key is invalid and needs to be recreated.
In order to perform this action, the recovery key needs to be supplied via the recoveryKey argument. The new key is provided via the key argument. The new key should be stored encrypted with SealKeyToTPM.
Note that this operation is not atomic. It will delete the existing key from the container before configuring the keyslot with the new key. This is not a problem, because this function is intended to be called in the scenario that the default key cannot be used to activate the LUKS2 container.
func DeactivateVolume ¶
DeactivateVolume attempts to deactivate the LUKS encrypted volumeName. This makes use of systemd-cryptsetup.
func InitializeLUKS2Container ¶
func InitializeLUKS2Container(devicePath, label string, key []byte, options *InitializeLUKS2ContainerOptions) error
InitializeLUKS2Container will initialize the partition at the specified devicePath as a new LUKS2 container. This can only be called on a partition that isn't mapped. The label for the new LUKS2 container is provided via the label argument.
The initial key used for unlocking the container is provided via the key argument, and must be a cryptographically secure random number of at least 32-bytes. The key should be encrypted by using SealKeyToTPM.
The container will be configured to encrypt data with AES-256 and XTS block cipher mode.
On failure, this will return an error containing the output of the cryptsetup command.
WARNING: This function is destructive. Calling this on an existing LUKS container will make the data contained inside of it irretrievable.
func RegisterPlatformKeyDataHandler ¶
func RegisterPlatformKeyDataHandler(name string, handler PlatformKeyDataHandler)
RegisterPlatformKeyDataHandler registers a handler for the specified platform name.
Types ¶
type ActivateVolumeOptions ¶
type ActivateVolumeOptions struct { // PassphraseTries specifies the maximum number of times // that unsealing with a user passphrase should be attempted // before failing with an error and falling back to activating // with the recovery key (see RecoveryKeyTries). // Setting this to zero disables unsealing with a user // passphrase - in this case, an error will be returned if the // sealed key object indicates that a user passphrase has been // set. // With a TPM, attempts to unseal will stop if the TPM enters // dictionary attack lockout mode before this limit is // reached. // It is ignored by ActivateWithRecoveryKey. PassphraseTries int // RecoveryKeyTries specifies the maximum number of times that // activation with the fallback recovery key should be // attempted. // It is used directly by ActivateWithRecoveryKey and // indirectly with other methods upon failure, for example // failed TPM unsealing. Setting this to zero will disable // attempts to activate with the fallback recovery key. RecoveryKeyTries int // KeyringPrefix is the prefix used for the description of any // kernel keys created during activation. KeyringPrefix string }
ActivateVolumeOptions provides options to the ActivateVolumeWith* family of functions.
type AuthRequestor ¶
type AuthRequestor interface { // RequestPassphrase is used to request the passphrase for a platform // protected key that is being used to unlock the container at the // specified sourceDevicePath. RequestPassphrase(volumeName, sourceDevicePath string) (string, error) // RequestRecoveryKey is used to request the recovery key to unlock the // container at the specified sourceDevicePath. RequestRecoveryKey(volumeName, sourceDevicePath string) (RecoveryKey, error) }
AuthRequestor is an interface for requesting credentials.
func NewSystemdAuthRequestor ¶
func NewSystemdAuthRequestor(passphraseTmpl, recoveryKeyTmpl string) (AuthRequestor, error)
NewSystemdAuthRequestor creates an implementation of AuthRequestor that delegates to the systemd-ask-password binary. The supplied templates are used to compose the messages that will be displayed when requesting a credential. The template will be executed with the following parameters: - .VolumeName: The name that the LUKS container will be mapped to. - .SourceDevicePath: The device path of the LUKS container.
type AuxiliaryKey ¶
type AuxiliaryKey []byte
AuxiliaryKey is an additional key used to modify properties of a KeyData object without having to create a new object.
func GetAuxiliaryKeyFromKernel ¶
func GetAuxiliaryKeyFromKernel(prefix, devicePath string, remove bool) (AuxiliaryKey, error)
GetAuxiliaryKeyFromKernel retrieves the auxiliary key associated with the KeyData that was used to unlock the encrypted container at the specified path. The value of prefix must match the prefix that was supplied via ActivateVolumeOptions during unlocking.
If remove is true, the key will be removed from the kernel keyring prior to returning.
If no key is found, a ErrKernelKeyNotFound error will be returned.
type DiskUnlockKey ¶
type DiskUnlockKey []byte
DiskUnlockKey is the key used to unlock a LUKS volume.
func GetDiskUnlockKeyFromKernel ¶
func GetDiskUnlockKeyFromKernel(prefix, devicePath string, remove bool) (DiskUnlockKey, error)
GetDiskUnlockKeyFromKernel retrieves the key that was used to unlock the encrypted container at the specified path. The value of prefix must match the prefix that was supplied via ActivateVolumeOptions during unlocking.
If remove is true, the key will be removed from the kernel keyring prior to returning.
If no key is found, a ErrKernelKeyNotFound error will be returned.
type FileKeyDataReader ¶
FileKeyDataReader provides a mechanism to read a KeyData from a file.
func NewFileKeyDataReader ¶
func NewFileKeyDataReader(path string) (*FileKeyDataReader, error)
NewFileKeyDataReader is used to read a file containing key data at the specified path.
func (*FileKeyDataReader) ReadableName ¶
func (r *FileKeyDataReader) ReadableName() string
type FileKeyDataWriter ¶
FileKeyDataWriter provides a mechanism to write a KeyData to a file.
func NewFileKeyDataWriter ¶
func NewFileKeyDataWriter(path string) *FileKeyDataWriter
NewFileKeyDataWriter creates a new FileKeyDataWriter for atomically writing a KeyData to a file.
func (*FileKeyDataWriter) Commit ¶
func (w *FileKeyDataWriter) Commit() error
type InitializeLUKS2ContainerOptions ¶
type InitializeLUKS2ContainerOptions struct { // MetadataKiBSize sets the size of the LUKS2 metadata (JSON) area, // expressed in multiples of 1024 bytes. The value includes 4096 bytes // for the binary metadata. According to LUKS2 specification and // cryptsetup(8), only these values are valid: 16, 32, 64, 128, 256, // 512, 1024, 2048 and 4096 KiB. MetadataKiBSize int // KeyslotsAreaSize sets the size of the LUKS2 binary keyslot area, // expressed in multiples of 1024 bytes. The value must be aligned to // 4096 bytes, with the maximum size of 128MB. KeyslotsAreaKiBSize int // KDFOptions sets the KDF options for the initial keyslot. If this // is nil then the defaults are used. KDFOptions *KDFOptions }
InitializeLUKS2ContainerOptions carries options for initializing LUKS2 containers.
type InvalidKeyDataError ¶
type InvalidKeyDataError struct {
// contains filtered or unexported fields
}
InvalidKeyDataError is returned from any of the KeyData.RecoverKeys* functions if the keys cannot be successfully recovered because the key data is invalid in some way.
func (*InvalidKeyDataError) Error ¶
func (e *InvalidKeyDataError) Error() string
func (*InvalidKeyDataError) Unwrap ¶
func (e *InvalidKeyDataError) Unwrap() error
type KDFOptions ¶
type KDFOptions struct { // MemoryKiB specifies the maximum memory cost in KiB when ForceIterations // is zero. If ForceIterations is not zero, then this is used as the // memory cost. MemoryKiB int // TargetDuration specifies the target duration for the KDF which // is used to benchmark the time and memory cost parameters. If it // is zero then the cryptsetup default is used. If ForceIterations // is not zero then this field is ignored. TargetDuration time.Duration // ForceIterations can be used to turn off KDF benchmarking by // setting the time cost directly. If this is zero then the cost // parameters are benchmarked based on the value of TargetDuration. ForceIterations int // Parallel sets the maximum number of parallel threads for the // KDF (up to 4). Cryptsetup will adjust this downwards based on // the actual number of CPUs. Parallel int }
KDFOptions specifies parameters for the Argon2 KDF used by cryptsetup.
type KeyCreationData ¶
type KeyCreationData struct { PlatformKeyData PlatformName string // Name of the platform that produced this data // AuxiliaryKey is a key used to authorize changes to the key data. // It must match the key protected inside PlatformKeyData.EncryptedPayload. AuxiliaryKey AuxiliaryKey // SnapModelAuthHash is the digest algorithm used for HMACs of Snap // device models, and also the digest algorithm used to produce the // key digest. SnapModelAuthHash crypto.Hash }
KeyCreationData is the data required to create a new KeyData object. It should be produced by a platform implementation.
type KeyData ¶
type KeyData struct {
// contains filtered or unexported fields
}
KeyData represents a disk unlock key and auxiliary key protected by a platform's secure device.
func NewKeyData ¶
func NewKeyData(creationData *KeyCreationData) (*KeyData, error)
NewKeyData creates a new KeyData object using the supplied KeyCreationData, which should be created by a platform-specific package, containing a payload encrypted by the platform's secure device and the associated handle required for subsequent recovery of the keys.
func ReadKeyData ¶
func ReadKeyData(r KeyDataReader) (*KeyData, error)
ReadKeyData reads the key data from the supplied KeyDataReader, returning a new KeyData object.
func (*KeyData) AuthMode ¶
AuthMode indicates the authentication mechanisms enabled for this key data.
func (*KeyData) IsSnapModelAuthorized ¶
func (d *KeyData) IsSnapModelAuthorized(auxKey AuxiliaryKey, model SnapModel) (bool, error)
IsSnapModelAuthorized indicates whether the supplied Snap device model is trusted to access the data on the encrypted volume protected by this key data.
The supplied auxKey is obtained using one of the RecoverKeys* functions.
func (*KeyData) ReadableName ¶
ReadableName returns a human-readable name for this key data, useful for including in errors.
func (*KeyData) RecoverKeys ¶
func (d *KeyData) RecoverKeys() (DiskUnlockKey, AuxiliaryKey, error)
RecoverKeys recovers the disk unlock key and auxiliary key associated with this key data from the platform's secure device, for key data that doesn't have any additional authentication modes enabled (AuthMode returns AuthModeNone).
If AuthMode returns anything other than AuthModeNone, then this will return an error.
If no platform handler has been registered for this key data, an ErrNoPlatformHandlerRegistered error will be returned.
If the keys cannot be recovered because the key data is invalid, a *InvalidKeyDataError error will be returned.
If the keys cannot be recovered because the platform's secure device is not properly initialized, a *PlatformUninitializedError error will be returned.
If the keys cannot be recovered because the platform's secure device is not available, a *PlatformDeviceUnavailableError error will be returned.
func (*KeyData) SetAuthorizedSnapModels ¶
func (d *KeyData) SetAuthorizedSnapModels(auxKey AuxiliaryKey, models ...SnapModel) error
SetAuthorizedSnapModels marks the supplied Snap device models as trusted to access the data on the encrypted volume protected by this key data. This function replaces all previously trusted models.
This makes changes to the key data, which will need to persisted afterwards using WriteAtomic.
The supplied auxKey is obtained using one of the RecoverKeys* functions. If the supplied auxKey is incorrect, then an error will be returned.
func (*KeyData) WriteAtomic ¶
func (d *KeyData) WriteAtomic(w KeyDataWriter) error
WriteAtomic saves this key data to the supplied KeyDataWriter.
type KeyDataReader ¶
KeyDataReader is an interface used to read and decode a KeyData from persistent storage.
type KeyDataWriter ¶
KeyDataWriter is an interface used by KeyData to write the data to persistent storage in an atomic way.
type KeyID ¶
type KeyID []byte
KeyID is the unique ID for a KeyData object. It is used to facilitate the sharing of state between the early boot environment and OS runtime.
type KeyPayload ¶
type KeyPayload []byte
KeyPayload is the payload that should be encrypted by a platform's secure device.
func MarshalKeys ¶
func MarshalKeys(key DiskUnlockKey, auxKey AuxiliaryKey) KeyPayload
MarshalKeys serializes the supplied disk unlock key and auxiliary key in to a format that is ready to be encrypted by a platform's secure device.
func (KeyPayload) Unmarshal ¶
func (c KeyPayload) Unmarshal() (key DiskUnlockKey, auxKey AuxiliaryKey, err error)
Unmarshal obtains the keys from this payload.
type PlatformDeviceUnavailableError ¶
type PlatformDeviceUnavailableError struct {
// contains filtered or unexported fields
}
PlatformDeviceUnavailableError is returned from any of the KeyData.RecoverKeys* functions if the keys cannot be recovered because the platform's secure device is currently unavailable.
func (*PlatformDeviceUnavailableError) Error ¶
func (e *PlatformDeviceUnavailableError) Error() string
func (*PlatformDeviceUnavailableError) Unwrap ¶
func (e *PlatformDeviceUnavailableError) Unwrap() error
type PlatformKeyData ¶
type PlatformKeyData struct { // Handle contains metadata required by the platform in order to recover // this key. It is opaque to this go package. It should be an encoded JSON // value, which could be something as simple as a single string containing // a base64 encoded binary payload or a more complex JSON object, depending // on the requirements of the implementation. Handle []byte EncryptedPayload []byte // The encrypted payload }
PlatformKeyData represents the data exchanged between this package and platform implementations.
type PlatformKeyDataHandler ¶
type PlatformKeyDataHandler interface { // RecoverKeys attempts to recover the cleartext keys from the supplied key // data using this platform's secure device. RecoverKeys(data *PlatformKeyData) (KeyPayload, error) }
PlatormKeyDataHandler is the interface that this go package uses to interact with a platform's secure device for the purpose of recovering keys.
type PlatformKeyRecoveryError ¶ added in v0.0.9
type PlatformKeyRecoveryError struct { Type PlatformKeyRecoveryErrorType // type of the error Err error // underlying error }
PlatformKeyRecoveryError is returned from any of the PlatformKeyDataHandler.RecoverKeys* functions if the keys cannot be successfully recovered by the platform's secure device.
func (*PlatformKeyRecoveryError) Error ¶ added in v0.0.9
func (e *PlatformKeyRecoveryError) Error() string
func (*PlatformKeyRecoveryError) Unwrap ¶ added in v0.0.9
func (e *PlatformKeyRecoveryError) Unwrap() error
type PlatformKeyRecoveryErrorType ¶ added in v0.0.9
type PlatformKeyRecoveryErrorType int
PlatformKeyRecoveryErrorType describes the type of error returned from one of the PlatformKeyDataHandler.RecoverKeys* functions.
const ( // PlatformKeyRecoveryErrorInvalidData indicates that keys could not be // recovered successfully because the supplied data is invalid. PlatformKeyRecoveryErrorInvalidData PlatformKeyRecoveryErrorType = iota + 1 // PlatformKeyRecoveryErrorUninitialized indicates that keys could not be // recovered successfully because the platform's secure device is not properly // initialized. PlatformKeyRecoveryErrorUninitialized // recovered successfully because the platform's secure device is unavailable. PlatformKeyRecoveryErrorUnavailable )
type PlatformUninitializedError ¶
type PlatformUninitializedError struct {
// contains filtered or unexported fields
}
PlatformUninitializedError is returned from any of the KeyData.RecoverKeys* functions if the keys cannot be successfully recovered because the platform's secure device has not been initialized properly.
func (*PlatformUninitializedError) Error ¶
func (e *PlatformUninitializedError) Error() string
func (*PlatformUninitializedError) Unwrap ¶
func (e *PlatformUninitializedError) Unwrap() error
type RecoveryKey ¶
type RecoveryKey [16]byte
RecoveryKey corresponds to a 16-byte recovery key in its binary form.
func ParseRecoveryKey ¶
func ParseRecoveryKey(s string) (out RecoveryKey, err error)
ParseRecoveryKey interprets the supplied string and returns the corresponding RecoveryKey. The recovery key is a 16-byte number, and the formatted version of this is represented as 8 5-digit zero-extended base-10 numbers (each with a range of 00000-65535) which may be separated by an optional '-', eg:
"61665-00531-54469-09783-47273-19035-40077-28287"
The formatted version of the recovery key is designed to be able to be inputted on a numeric keypad.
func (RecoveryKey) String ¶
func (k RecoveryKey) String() string
type SnapModel ¶
type SnapModel interface { Series() string BrandID() string Model() string Classic() bool Grade() asserts.ModelGrade SignKeyID() string }
SnapModel exposes the details of a snap device model that are bound to an encrypted container.
type SnapModelChecker ¶ added in v0.0.9
type SnapModelChecker interface { // IsModelAuthorized indicates whether the supplied Snap device model is // authorized to access the data on the decrypted volume with the device // mapper name returned by VolumeName. IsModelAuthorized(model SnapModel) (bool, error) // VolumeName is the device mapper name of the volume associated with this // SnapModelChecker. VolumeName() string }
SnapModelChecker is used for verifying whether a Snap device model is authorized to access the data on a volume unlocked by this package.
func ActivateVolumeWithKeyData ¶
func ActivateVolumeWithKeyData(volumeName, sourceDevicePath string, key *KeyData, options *ActivateVolumeOptions) (SnapModelChecker, error)
ActivateVolumeWithKeyData attempts to activate the LUKS encrypted container at sourceDevicePath and create a mapping with the name volumeName, using the supplied KeyData to recover the disk unlock key from the platform's secure device. This makes use of systemd-cryptsetup.
If activation with the supplied KeyData fails, this function will attempt to activate it with the fallback recovery key instead. The fallback recovery key will be requested using systemd-ask-password. The RecoveryKeyTries field of options specifies how many attempts should be made to activate the volume with the recovery key before failing. If this is set to 0, then no attempts will be made to activate the encrypted volume with the fallback recovery key.
If either the PassphraseTries or RecoveryKeyTries fields of options are less than zero, an error will be returned.
If activation with the supplied KeyData succeeds, a SnapModelChecker will be returned so that the caller can check whether a particular Snap device model has previously been authorized to access the data on this volume. If the fallback recovery key is used for successfully for activation, no SnapModelChecker will be returned and a ErrRecoveryKeyUsed error will be returned.
If activation fails, an error will be returned.
func ActivateVolumeWithMultipleKeyData ¶
func ActivateVolumeWithMultipleKeyData(volumeName, sourceDevicePath string, keys []*KeyData, options *ActivateVolumeOptions) (SnapModelChecker, error)
ActivateVolumeWithKeyData attempts to activate the LUKS encrypted container at sourceDevicePath and create a mapping with the name volumeName, using the supplied KeyData objects to recover the disk unlock key from the platform's secure device. This makes use of systemd-cryptsetup.
If activation with the supplied KeyData objects fails, this function will attempt to activate it with the fallback recovery key instead. The fallback recovery key will be requested using systemd-ask-password. The RecoveryKeyTries field of options specifies how many attempts should be made to activate the volume with the recovery key before failing. If this is set to 0, then no attempts will be made to activate the encrypted volume with the fallback recovery key.
If either the PassphraseTries or RecoveryKeyTries fields of options are less than zero, an error will be returned.
If activation with one of the supplied KeyData objects succeeds, a SnapModelChecker will be returned so that the caller can check whether a particular Snap device model has previously been authorized to access the data on this volume. If the fallback recovery key is used for successfully for activation, no SnapModelChecker will be returned and a ErrRecoveryKeyUsed error will be returned.
If activation fails, an error will be returned.