2022-09-05 03:06:08 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2023-07-17 07:55:31 -04:00
|
|
|
// Package diskencryption handles interaction with a node's state disk.
|
2022-04-20 05:35:23 -04:00
|
|
|
package diskencryption
|
2023-07-17 07:55:31 -04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/edgelesssys/constellation/v2/internal/cryptsetup"
|
|
|
|
"github.com/spf13/afero"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
stateMapperDevice = "state"
|
|
|
|
initialKeyPath = "/run/cryptsetup-keys.d/state.key"
|
|
|
|
keyslot = 0
|
|
|
|
)
|
|
|
|
|
|
|
|
// DiskEncryption manages the encrypted state mapper device.
|
|
|
|
type DiskEncryption struct {
|
|
|
|
fs afero.Fs
|
|
|
|
device cryptdevice
|
|
|
|
}
|
|
|
|
|
|
|
|
// New creates a new Cryptsetup.
|
|
|
|
func New() *DiskEncryption {
|
|
|
|
return &DiskEncryption{
|
|
|
|
fs: afero.NewOsFs(),
|
|
|
|
device: cryptsetup.New(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open opens the cryptdevice.
|
|
|
|
func (c *DiskEncryption) Open() (free func(), err error) {
|
|
|
|
return c.device.InitByName(stateMapperDevice)
|
|
|
|
}
|
|
|
|
|
|
|
|
// UUID gets the device's UUID.
|
|
|
|
// Only works after calling Open().
|
|
|
|
func (c *DiskEncryption) UUID() (string, error) {
|
|
|
|
return c.device.GetUUID()
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdatePassphrase switches the initial random passphrase of the mapped crypt device to a permanent passphrase.
|
|
|
|
// Only works after calling Open().
|
|
|
|
func (c *DiskEncryption) UpdatePassphrase(passphrase string) error {
|
|
|
|
initialPassphrase, err := c.getInitialPassphrase()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-07-18 10:20:03 -04:00
|
|
|
if err := c.device.KeyslotChangeByPassphrase(keyslot, keyslot, initialPassphrase, passphrase); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set token as initialized.
|
|
|
|
return c.device.SetConstellationStateDiskToken(cryptsetup.SetDiskInitialized)
|
2023-07-17 07:55:31 -04:00
|
|
|
}
|
|
|
|
|
2024-03-12 06:43:38 -04:00
|
|
|
// MarkDiskForReset marks the state disk as not initialized so it may be wiped (reset) on reboot.
|
|
|
|
func (c *DiskEncryption) MarkDiskForReset() error {
|
|
|
|
return c.device.SetConstellationStateDiskToken(cryptsetup.SetDiskNotInitialized)
|
|
|
|
}
|
|
|
|
|
2023-07-17 07:55:31 -04:00
|
|
|
// getInitialPassphrase retrieves the initial passphrase used on first boot.
|
|
|
|
func (c *DiskEncryption) getInitialPassphrase() (string, error) {
|
|
|
|
passphrase, err := afero.ReadFile(c.fs, initialKeyPath)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("reading first boot encryption passphrase from disk: %w", err)
|
|
|
|
}
|
|
|
|
return string(passphrase), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type cryptdevice interface {
|
|
|
|
InitByName(name string) (func(), error)
|
|
|
|
GetUUID() (string, error)
|
|
|
|
KeyslotChangeByPassphrase(currentKeyslot int, newKeyslot int, currentPassphrase string, newPassphrase string) error
|
2023-07-18 10:20:03 -04:00
|
|
|
SetConstellationStateDiskToken(bool) error
|
2023-07-17 07:55:31 -04:00
|
|
|
}
|