Raspberry PiでLUKS暗号化ファイルシステムが開けない

先日PCで暗号化FSを設定したHDDですが，

USB HDDをLUKS&Btrfsで初期化 – matoken’s meme

SBCのRaspberry Piに接続してマウントしようとしたところ失敗しました．

RaspberryPiでopenしようとしたら失敗

$ sudo cryptsetup open -S0 /dev/sda crypthdd
Enter passphrase for /dev/sda:
Warning: keyslot operation could fail as it requires more than available memory.
Killed

メモリ不足でRaspberry Piで開けない

メッセージではメモリが足りなそうです．

Warning: keyslot operation could fail as it requires more than available memory.

試したのはRaspberry Pi 3 model BでRAM 1GBのarm端末です．このHDDを設定した端末のRAMは16GBでした．

1GBもあって失敗するのもなのかなと思いつつswapファイルを作り，一時的にswapを4GBほど追加してみても1時間以上経っても戻ってきませんでした．諦めて途中で終了しました．

swapファイルを作りswapを追加

$ sudo install -m 0600 -o 0 -g 0 /dev/null /var/tmp/swap.img
$ sudo dd if=/dev/zero of=/var/tmp/swap.img bs=1M count=4096
$ sudo mkswap /var/tmp/swap.img
$ sudo swapon /var/tmp/swap.img

keyslotのメモリを制限したり，古いアルゴリズムを指定

Raspberry Pi側で再度cryptsetup luksFormatからやり直しかなと思ったのですが，一旦セットアップしたPCに接続し直して，新しいキースロットを --pbkdf-memory でメモリを制限したり, --pbkdf pbkdf2 のように古いアルゴリズムを指定することでRAM 1GBのRaspberry Piでもopenすることが出来ました．

PCで作ったkeyslot 0の情報

$ sudo cryptsetup luksDump /dev/sdb | grep "0: luks2" -A 15
0: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 6
Memory: 1048576
Threads: 4
Salt: 60 50 4a 09 0d ed 44 1d 53 52 04 f5 71 15 58 40
42 8b 7d 36 8f 7c f7 b5 2f 7f af 79 1f 68 e8 29
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0

keyslot1のアルゴリズムに pbkdf2 を利用

$ sudo cryptsetup luksAddKey --pbkdf pbkdf2 -S 1 /dev/sda
WARNING: The --key-slot parameter is used for new keyslot number.
Enter any existing passphrase:
Enter new passphrase for key slot:
Verify passphrase:
$ sudo cryptsetup luksDump /dev/sdb | grep "1: luks2" -A 14 (1)
1: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: pbkdf2
Hash: sha256
Iterations: 1669706
Salt: 4b a5 42 b1 41 ce 0b 5f 14 f6 da 05 a8 ad f7 7f
23 60 d1 03 c4 18 ce ca f4 fa 63 56 04 f0 b8 a5
AF stripes: 4000
AF hash: sha256
Area offset:290816 [bytes]
Area length:258048 [bytes]
Digest ID: 0

keyslot 2のmemoryをPCで作成したkeyslotの半分で設定

$ echo $(sudo cryptsetup luksDump /dev/sda | grep "0: luks2" -A 14 | grep Memory: | cut -f6- -d\ )/2 | bc
524288
$ sudo cryptsetup luksAddKey -S 2 --pbkdf-memory=524288 /dev/sda
WARNING: The --key-slot parameter is used for new keyslot number.
Enter any existing passphrase:
Enter new passphrase for key slot:
Verify passphrase:
$ sudo cryptsetup luksDump /dev/sda | grep "2: luks2" -A15
2: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 10
Memory: 524288
Threads: 4
Salt: 9c 04 4e e9 db 79 4e db 67 41 99 96 0d b4 a5 66
4f 6d 0d 7f fd 8d e5 60 5b c1 b3 12 6d f2 df ba
AF stripes: 4000
AF hash: sha256
Area offset:1064960 [bytes]
Area length:258048 [bytes]
Digest ID: 0

Tip

ここでのMemoryの単位はkilobytesです．

Raspberry Piでopen出来るか試す

$ sudo cryptsetup open -S1 /dev/sda chdd (1)
Enter passphrase for /dev/sda:
$ sudo cryptsetup close chdd
$ sudo cryptsetup open -S2 /dev/sda chdd (2)
Enter passphrase for /dev/sda:
Warning: keyslot operation could fail as it requires more than available memory. (3)
$ ls -l /dev/mapper/chdd
lrwxrwxrwx 1 root root 7 Nov 15 05:58 /dev/mapper/chdd -> ../dm-0
$ sudo cryptsetup close chdd

pdkdf2のkeyslot1をopen

argon2id/Memory 523288のkeyslot2をopen

警告が出るがopen出来た

Tip

keyslotは0からはじまりLUKS1は8slot，LUKS2では32slot利用可能です．

Raspberry Piでopenできないkeyslotを削除

Raspberry Piでopenできないkeyslotは邪魔なので消してしまいます．

PCでRaspberry Piでopenできないkeyslot 0をkill

$ sudo cryptsetup luksKillSlot /dev/sdb 0
Enter any remaining passphrase:

Raspberry Pi既定値でkeyslotを設定

オプションを指定しなかったらその端末にあった設定になると思うので既定値で設定してみます．

Raspberry Piで新しいkeyslotを規定値で設定

$ sudo cryptsetup luksAddKey -S4 /dev/sda
WARNING: The --key-slot parameter is used for new keyslot number.
Enter any existing passphrase:
Enter new passphrase for key slot:
Verify passphrase:
$ sudo cryptsetup luksDump /dev/sda | grep "4: luks2" -A15
4: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 4
Memory: 170223 (1)
Threads: 4
Salt: 2d 06 67 aa 97 1f fd d5 02 72 54 ab a5 31 9b 9d
83 18 12 cd c1 2f 98 56 a5 4a 75 10 ea eb 7b bc
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0

PCで作成したkeyslot0と比べると主にTime costとMemoryが変わりました．メモリ量は大分減りました．

| PC | Pi

Time cost

10

4

Memory

1048576

170223

スペック差のある端末間でLUKSを利用するときは注意

今回CPU Intel第10世代，RAM 16GBのlaptopのcryptsetupで暗号化ファイルシステムを作成，SOC Broadcom BCM2837(1.2GHz 64-bit quad-core ARMv8 Cortex-A53)，RAM 1GBのSBCのRaspberry Pi 3 model Bで利用しようとopenしようとしたところでメモリ不足で失敗しました．
cryptsetupはluksAddkeyを行うときにベンチマークを実行し，環境に合ったkeyslotを作ろうとするようです．そのためスペックさがある場合は一番低スペックな端末で設定するか，cryptsetup benchmarkを実行してその結果を参考に設定するようにしたほうが良さそうです．そうでないと今回のように低スペックな端末で開けないといったことが起きます．

余録1）crypttabとfstabでsystemd手動マウント設定

ここは余録です．systemdで手動マウントするようしてみました．
手動マントの場合は前設定の手間を考えると全部手動でも良いような感じもします．

$ sudo cryptsetup luksDump /dev/sda | grep "UUID" (1)
UUID: 28dee849-e142-49bc-96c2-be62adfc9309
$ sudo install -o0 -g0 -m0600 /dev/null /etc/crypttab (2)
$ echo "crypthdd UUID=28dee849-e142-49bc-96c2-be62adfc9309 none luks,discard,keyslot=1,noauto" | sudo tee /etc/crypttab (3)
crypthdd UUID=28dee849-e142-49bc-96c2-be62adfc9309 none luks,discard,keyslot=1,noauto
$ echo "/dev/mapper/crypthdd /mnt btrfs nodev,noexec,noauto,compress=zstd,nofail,x-systemd.automount,x-systemd.device-timeout=30 0 0" \
| sudo tee -a /etc/fstab (4)
/dev/mapper/crypthdd /mnt btrfs nodev,noexec,noauto,compress=zstd,nofail,x-systemd.automount,x-systemd.device-timeout=30 0 0
$ sudo systemctl daemon-reload (5)
$ sudo systemctl start systemd-cryptsetup@crypthdd.service (6)
Please enter passphrase for disk 541050A9E680 (crypthdd) on /mnt: (no echo)
$ df /mnt (7)
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/crypthdd 488370200 5920 486255616 1% /mnt
$ mount | grep /mnt
systemd-1 on /mnt type autofs (rw,relatime,fd=46,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)
/dev/mapper/crypthdd on /mnt type btrfs (rw,nodev,noexec,relatime,compress=zstd:3,space_cache=v2,subvolid=5,subvol=/,x-systemd.automount)

LUKSデバイスのUUIDを確認

crypttabを作成

crypttabを設定

fstabに追記

systemdに反映

LUKS手動アンロック

マウントポイントにアクセスすると自動マウント

余録2)LUKS1の頃のDump

ThinkPad X201s(CPU:Core i7 620L/RAM:8GB)で設定したと思う古いdiskもあったのでluksDumpを見てみるとこんな感じでした．

$ sudo cryptsetup luksDump /dev/sdb
LUKS header information for /dev/sdb

Version: 1
Cipher name: aes
Cipher mode: cbc-essiv:sha256
Hash spec: sha1
Payload offset: 2056
MK bits: 256
MK digest: 55 fc 34 22 89 b0 e5 65 f1 cb fd 34 96 2f 2c 16 6a 62 e7 24
MK salt: e3 fe 28 46 06 36 00 36 c6 e0 0c 9b e9 7a 2f ea
6e 3b 96 ee b0 f9 33 fd 2a 60 8d 2d 87 fe de bd
MK iterations: 12500
UUID: ac5b8484-4b26-4967-b336-f63c408bb17d

Key Slot 0: ENABLED
Iterations: 50352
Salt: 08 7d 85 89 39 0e 94 6e e8 2f ab 3d ab 18 e1 17
37 50 a5 ce fe d4 e1 78 e1 4f a2 59 d3 4c bb 54
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

環境

PC環境

$ dpkg-query -W cryptsetup
cryptsetup 2:2.7.5-1
$ lsb_release -dr
Description: Debian GNU/Linux trixie/sid
Release: n/a
$ arch
x86_64
$ lscpu | grep "^Model name:"
Model name: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
$ head -1 /proc/meminfo
MemTotal: 15992644 kB

Raspberry Pi

$ dpkg-query -W cryptsetup
cryptsetup 2:2.6.1-4~deb12u2
$ lsb_release -dr
No LSB modules are available.
Description: Raspbian GNU/Linux 12 (bookworm)
Release: 12
$ arch
armv7l
$ grep "^Hardware" /proc/cpuinfo
Hardware : BCM2835
$ grep "^Model" /proc/cpuinfo
Model : Raspberry Pi 3 Model B Rev 1.2