#!/bin/sh # # beacon-encrypt-data.sh # # On first boot: LUKS2-format /dev/mmcblk0p3 with device OTP key, create ext4, mount /data # On later boots: open LUKS2 container with device OTP key, mount /data # # If the OTP key is all-zeros (not programmed) the partition is mounted unencrypted # so the system is still usable on a non-secure-boot device during development. set -e DATA_DEV="/dev/mmcblk0p3" MAPPER_NAME="data" MAPPER_DEV="/dev/mapper/${MAPPER_NAME}" MOUNT_POINT="/data" OTP_TOOL="/usr/sbin/beacon-otp-key" log() { echo "beacon-encrypt-data: $*"; } die() { echo "beacon-encrypt-data: ERROR: $*" >&2; exit 1; } # Block device must exist [ -b "${DATA_DEV}" ] || { log "${DATA_DEV} not found, skipping"; exit 0; } # OTP tool must exist [ -x "${OTP_TOOL}" ] || die "OTP tool not found at ${OTP_TOOL}" # Write OTP key into a tmpfs file so it never touches disk KEY_FILE="$(mktemp /dev/shm/otp-XXXXXX 2>/dev/null || mktemp /tmp/otp-XXXXXX)" trap 'rm -f "${KEY_FILE}"' EXIT INT TERM OTP_READ_OK=1 if ! ${OTP_TOOL} -b > "${KEY_FILE}"; then log "WARNING: OTP key read failed — falling back to unencrypted /data" OTP_READ_OK=0 fi # Check if key is all zeros (OTP not programmed — dev/test device) KEY_HEX="" if [ "${OTP_READ_OK}" = "1" ]; then KEY_HEX="$(${OTP_TOOL} 2>/dev/null || true)" fi mount_unencrypted() { if ! blkid "${DATA_DEV}" >/dev/null 2>&1; then log "No filesystem on ${DATA_DEV} — creating ext4 (unencrypted)" mkfs.ext4 -q -L "Data" "${DATA_DEV}" || die "mkfs.ext4 failed" fi mount -t ext4 -o defaults,noatime "${DATA_DEV}" "${MOUNT_POINT}" \ || die "mount ${MOUNT_POINT} failed" log "${MOUNT_POINT} is ready (unencrypted)" exit 0 } if [ "${OTP_READ_OK}" = "0" ] || [ -z "$(echo "${KEY_HEX}" | tr -d '0')" ]; then log "OTP key is all-zeros or unreadable — mounting ${DATA_DEV} unencrypted" mount_unencrypted fi # --- Encrypted path --- luks_format() { log "Formatting /dev/mmcblk0p3 with LUKS2" dd if=/dev/zero of="${DATA_DEV}" bs=1M count=4 status=none 2>/dev/null || true cryptsetup luksFormat \ --batch-mode \ --type luks2 \ --key-file "${KEY_FILE}" \ --key-size 512 \ --cipher aes-xts-plain64 \ --hash sha256 \ --pbkdf pbkdf2 \ "${DATA_DEV}" \ || die "luksFormat failed" cryptsetup luksOpen "${DATA_DEV}" "${MAPPER_NAME}" \ --key-file "${KEY_FILE}" \ || die "luksOpen after format failed" log "Creating ext4 filesystem inside encrypted container" mkfs.ext4 -q -L "DataEnc" "${MAPPER_DEV}" \ || die "mkfs.ext4 failed" } if cryptsetup isLuks "${DATA_DEV}" 2>/dev/null; then log "Opening existing LUKS2 container on ${DATA_DEV}" if ! cryptsetup luksOpen "${DATA_DEV}" "${MAPPER_NAME}" \ --key-file "${KEY_FILE}" 2>/dev/null; then log "WARNING: luksOpen failed (stale header or wrong key) — re-formatting" luks_format fi else log "No LUKS header on ${DATA_DEV} — formatting with LUKS2 (first boot)" luks_format fi log "Mounting ${MAPPER_DEV} at ${MOUNT_POINT}" mount -t ext4 -o defaults,noatime "${MAPPER_DEV}" "${MOUNT_POINT}" \ || die "mount ${MOUNT_POINT} failed" log "${MOUNT_POINT} is ready (encrypted)"