Skip to content

Commit

Permalink
fixup! initializer/cryptsetup: add setupEncryptedMount
Browse files Browse the repository at this point in the history
  • Loading branch information
jmxnzo committed Jan 21, 2025
1 parent 793d56f commit a6c11ec
Showing 1 changed file with 4 additions and 71 deletions.
75 changes: 4 additions & 71 deletions initializer/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,11 @@ import (
"strconv"
"strings"
"syscall"
"crypto/rand"

"github.com/edgelesssys/contrast/internal/logger"
"github.com/spf13/cobra"
)

const (
// tmpPassphrase is the path to a temporary passphrase file, used for initial formatting.
tmpPassphrase = "/dev/shm/key"
// encryptionPassphrase is the path to the disk encryption passphrase file.
encryptionPassphrasePrefix = "/dev/shm/disk-key"
)

// luksVolume struct holds the representative attributes related to a LUKS encrypted volume.
type luksVolume struct {
devicePath string
Expand Down Expand Up @@ -86,10 +78,9 @@ func parseSetupEncryptedMountFlags(cmd *cobra.Command) (*luksVolume, error) {
hash := md5.Sum([]byte(devicePath + mountPoint))
mappingName := hex.EncodeToString(hash[:8])
return &luksVolume{
devicePath: devicePath,
mappingName: mappingName,
volumeMountPoint: mountPoint,
encryptionPassphrase: encryptionPassphrasePrefix + mappingName,
devicePath: devicePath,
mappingName: mappingName,
volumeMountPoint: mountPoint,
}, nil
}

Expand All @@ -106,22 +97,8 @@ func setupEncryptedMount(cmd *cobra.Command, _ []string) error {
}
ctx := cmd.Context()
if !isLuks(ctx, logger, luksVolume.devicePath) {
if err := createInitPassphrase(tmpPassphrase); err != nil {
return err
}
logger.Info("formatting csi device to LUKS with initial passphrase)")
// TODO(jmxnzo) check what happens if container is terminated in between formatting
if err := luksFormat(ctx, luksVolume.devicePath, tmpPassphrase); err != nil {
return err
}
if err := createEncryptionPassphrase(ctx, luksVolume, workloadSecretPath); err != nil {
return err
}
if err := luksChangeKey(ctx, luksVolume.devicePath, tmpPassphrase, luksVolume.encryptionPassphrase); err != nil {
return err
}
} else {
if err := createEncryptionPassphrase(ctx, luksVolume, workloadSecretPath); err != nil {
if err := luksFormat(ctx, luksVolume.devicePath, workloadSecretPath); err != nil {
return err
}
}
Expand Down Expand Up @@ -224,40 +201,6 @@ func mkfsExt4(ctx context.Context, devName string) error {
return nil
}

// createInitPassphrase creates a hardcoded string passphrase, to allow formatting the device to LUKS in order to get the UUID.
func createInitPassphrase(pathToPassphrase string) (err error) {
// The init_passphrase always has to be random to avoid reading LUKS header after initialization and extracting the master key.
initPassphrase := make([]byte, 32)
_, err = rand.Read(initPassphrase)
if err != nil {
return fmt.Errorf("Creating initial passphrase: %w", err)
}
err = os.WriteFile(pathToPassphrase, initPassphrase, 0o644)
if err != nil {
return fmt.Errorf("Writing initial passphrase: %w", err)
}
return nil
}

// createEncryptionPassphrase writes the UUID of the device and the current workload secret to the path of encryptionPassphrase in luksVolume.
func createEncryptionPassphrase(ctx context.Context, luksVolume *luksVolume, workloadSecretPath string) error {
blk, err := blkid(ctx, luksVolume.devicePath)
if err != nil {
return err
}
workloadSecretBytes, err := os.ReadFile(workloadSecretPath)
if err != nil {
return fmt.Errorf("reading workload secret: %w", err)
}
// Using UUID of the LUKS device ensures to not derive the same encryption key for multiple devices,
// still allowing reconstruction when UUID of device is known.
err = os.WriteFile(luksVolume.encryptionPassphrase, []byte(blk.UUID+string(workloadSecretBytes)), 0o644)
if err != nil {
return fmt.Errorf("writing encryption passphrase: %w", err)
}
return nil
}

// isLuks wraps the cryptsetup isLuks command and returns a bool reflecting if the device is formatted as LUKS.
func isLuks(ctx context.Context, logger *slog.Logger, devName string) bool {
cmd := exec.CommandContext(ctx, "cryptsetup", "isLuks", "--debug", devName)
Expand Down Expand Up @@ -289,16 +232,6 @@ func openEncryptedDevice(ctx context.Context, luksVolume *luksVolume) error {
return nil
}

// luksChangeKey wraps the luksChangeKey command.
func luksChangeKey(ctx context.Context, devName, oldKeyPath, newKeyPath string) error {
cmd := exec.CommandContext(ctx, "cryptsetup", "luksChangeKey", "--pbkdf-memory=10240", devName, "--key-file", oldKeyPath, newKeyPath)
_, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("cryptsetup luksChangeKey %s failed: %w", devName, err)
}
return nil
}

func mount(ctx context.Context, devName, mountPoint string) error {
if err := os.MkdirAll(mountPoint, 0o755); err != nil {
return fmt.Errorf("mkdir: %w", err)
Expand Down

0 comments on commit a6c11ec

Please sign in to comment.