Files
Arch-Linux-Installer/lib/disk/luks.sh
Logan Fick 6b70ce8a97 Refactored installer into modular library structure with improved error handling and logging.
The changes include:
- Split monolithic script into lib/, config/, profiles/, and files/ directories
- Added error handling with cleanup on failure
- Added installation logging to /var/log/arch-install.log
- Added username validation
2026-01-17 10:23:17 -05:00

170 lines
4.7 KiB
Bash

#!/bin/bash
# Copyright 2026 Logan Fick
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# luks.sh - LUKS encryption functions
#
# Manages full-disk encryption using LUKS2:
# - Prompts for encryption passphrase with confirmation
# - Formats partitions with LUKS2 using secure defaults from luks.conf
# - Opens/unlocks encrypted containers for filesystem creation
# - Supports both single-disk and RAID1 encryption setups
# - Securely clears passwords from memory after use
# Format a partition with LUKS encryption
# Arguments:
# $1 - partition path
# $2 - encryption password
setup_luks_encryption() {
local partition="$1"
local password="$2"
print "Setting up encryption on ${partition}..."
# Wrapped manually (not using run_visible_cmd) due to piped password input
echo -ne "${COLOR_BG_GRAY}"
echo -n "$password" | cryptsetup luksFormat \
--type "$LUKS_TYPE" \
--cipher "$LUKS_CIPHER" \
--hash "$LUKS_HASH" \
--key-size "$LUKS_KEY_SIZE" \
--pbkdf "$LUKS_PBKDF" \
--pbkdf-force-iterations "$LUKS_PBKDF_ITERATIONS" \
--pbkdf-memory "$LUKS_PBKDF_MEMORY" \
--pbkdf-parallel "$LUKS_PBKDF_PARALLEL" \
--use-urandom \
--key-file - \
"$partition"
echo -e "${COLOR_RESET}"
}
# Open (unlock) a LUKS container
# Arguments:
# $1 - partition path
# $2 - encryption password
# $3 - mapper name (e.g., cryptroot)
open_luks_container() {
local partition="$1"
local password="$2"
local mapper_name="$3"
print "Unlocking ${partition}..."
# Wrapped manually (not using run_visible_cmd) due to piped password input
echo -ne "${COLOR_BG_GRAY}"
echo -n "$password" | cryptsetup open \
--allow-discards \
--key-file - \
"$partition" \
"$mapper_name"
echo -e "${COLOR_RESET}"
}
# Get the UUID of a LUKS container
# Arguments:
# $1 - partition path
# Outputs:
# UUID to stdout
get_luks_uuid() {
local partition="$1"
cryptsetup luksDump "$partition" | grep 'UUID:' | awk '{print $2}'
}
# Close a LUKS container
# Arguments:
# $1 - mapper name
close_luks_container() {
local mapper_name="$1"
cryptsetup close "$mapper_name" 2>/dev/null || true
}
# Prompt for encryption password with confirmation
# Sets:
# ENCRYPTION_PASSWORD - the entered password
# Returns:
# 0 on success, 1 on mismatch
prompt_encryption_password() {
local password
local password_confirm
print "Please enter your desired encryption passphrase."
read -rs password
echo
print "Please confirm your encryption passphrase."
read -rs password_confirm
echo
if [ "$password" != "$password_confirm" ]; then
print_error "Passphrases do not match."
return 1
fi
ENCRYPTION_PASSWORD="$password"
unset password password_confirm
return 0
}
# Setup encryption for single-disk mode
# Arguments:
# $1 - root partition path
# Sets:
# LUKS_UUID - UUID of the LUKS container
setup_encryption_single() {
local root_partition="$1"
if ! prompt_encryption_password; then
exit 1
fi
setup_luks_encryption "$root_partition" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition" "$ENCRYPTION_PASSWORD" "cryptroot"
LUKS_UUID=$(get_luks_uuid "$root_partition")
# Clear password from memory
unset ENCRYPTION_PASSWORD
}
# Setup encryption for RAID1 mode
# Arguments:
# $1 - first root partition path
# $2 - second root partition path
# Sets:
# LUKS_UUID - UUID of the first LUKS container
# LUKS_UUID_2 - UUID of the second LUKS container
setup_encryption_raid1() {
local root_partition_1="$1"
local root_partition_2="$2"
if ! prompt_encryption_password; then
exit 1
fi
# Setup first disk
setup_luks_encryption "$root_partition_1" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_1" "$ENCRYPTION_PASSWORD" "cryptroot-primary"
LUKS_UUID=$(get_luks_uuid "$root_partition_1")
# Setup second disk
setup_luks_encryption "$root_partition_2" "$ENCRYPTION_PASSWORD"
open_luks_container "$root_partition_2" "$ENCRYPTION_PASSWORD" "cryptroot-secondary"
LUKS_UUID_2=$(get_luks_uuid "$root_partition_2")
# Clear password from memory
unset ENCRYPTION_PASSWORD
}