打开:cryptsetup 内存不足(“没有足够的可用内存来打开密钥槽。”)

Eag*_*One 8 encryption luks cryptsetup yocto

我正在开发 yocto 发行版,包括 2.3.2 版本中的 cryptsetup

我在具有 1 GB RAM 的主板上运行此类发行版,在尝试打开无法正确调试的加密分区时遇到“内存不足”错误。有任何想法吗?

我的发行版从具有 3 个分区的 mSD 运行;第三个 (30 MB) 是加密的。

我使用ArchLinux 指南中描述的步骤来加密该分区,使用 ext3 而不是 ext4

# cryptsetup -y -v luksFormat /dev/sda2
# cryptsetup open /dev/sda2 cryptroot
# mkfs.ext3 /dev/mapper/cryptroot
Run Code Online (Sandbox Code Playgroud)

但尝试在我的主板上打开该分区会引发错误:

cryptsetup --debug open /dev/mmcblk0p3  cryptroot
# cryptsetup 2.3.2 processing "cryptsetup --debug open /dev/mmcblk0p3 cryptroot"
# Running command open.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /dev/mmcblk0p3.
# Trying to open and read device /dev/mmcblk0p3 with direct-io.
# Initialising device-mapper backend library.
# Trying to load any crypt type from device /dev/mmcblk0p3.
# Crypto backend (OpenSSL 1.1.1k  25 Mar 2021) initialized in cryptsetup library version 2.3.2.
# Detected kernel Linux 4.1.35-rt41 ppc.
# Loading LUKS2 header (repair disabled).
# Acquiring read lock for device /dev/mmcblk0p3.
# Opening lock resource file /run/cryptsetup/L_179:3
# Verifying lock handle for /dev/mmcblk0p3.
# Device /dev/mmcblk0p3 READ lock taken.
# Trying to read primary LUKS2 header at offset 0x0.
# Opening locked device /dev/mmcblk0p3
# Veryfing locked device handle (bdev)
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:43e122216ab19330fdfb6d2f9d7b586c4e5189884aef24be884e7159228e9ee5 (on-disk)
# Checksum:43e122216ab19330fdfb6d2f9d7b586c4e5189884aef24be884e7159228e9ee5 (in-memory)
# Trying to read secondary LUKS2 header at offset 0x4000.
# Reusing open ro fd on device /dev/mmcblk0p3
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:4ed9a44c22fde04c4b59a638c20eba6da3a13e591a6a1cfe7e0fec4437dc14cc (on-disk)
# Checksum:4ed9a44c22fde04c4b59a638c20eba6da3a13e591a6a1cfe7e0fec4437dc14cc (in-memory)
# Device size 32505856, offset 16777216.
# Device /dev/mmcblk0p3 READ lock released.
# Only 1 active CPUs detected, PBKDF threads decreased from 4 to 1.
# Not enough physical memory detected, PBKDF max memory decreased from 1048576kB to 255596kB.
# PBKDF argon2i, time_ms 2000 (iterations 0), max_memory_kb 255596, parallel_threads 1.
# Activating volume cryptroot using token -1.
# Interactive passphrase entry requested.
Enter passphrase for /dev/mmcblk0p3:
# Activating volume cryptroot [keyslot -1] using passphrase.
device-mapper: ioctl: 4.31.0-ioctl (2015-3-12) initialised: dm-devel@redhat.com
# dm version   [ opencount flush ]   [16384] (*1)
# dm versions   [ opencount flush ]   [16384] (*1)
# Detected dm-ioctl version 4.31.0.
# Device-mapper backend running with UDEV support enabled.
# dm status cryptroot  [ opencount noflush ]   [16384] (*1)
# Keyslot 0 priority 1 != 2 (required), skipped.
# Trying to open LUKS2 keyslot 0.
# Keyslot 0 (luks2) open failed with -12.
Not enough available memory to open a keyslot.
# Releasing crypt device /dev/mmcblk0p3 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/mmcblk0p3.
# Unlocking memory.
Command failed with code -3 (out of memory).
Run Code Online (Sandbox Code Playgroud)

Voj*_*fny 9

LUKS2 使用Argon2i密钥派生函数,该函数对内存要求较高,这意味着它需要大量内存才能打开设备,以防止(或至少使其更难)使用 GPU 进行暴力攻击。您可以检查打开设备需要多少内存cryptsetup luksDump /dev/sda2,查找Memory: 755294下面的行Keyslots

创建设备时,cryptsetup检查可用内存量并相应调整打开所需的内存量,但如果您确实从另一台计算机(例如在桌面上格式化 SD 卡时)甚至在同一台计算机上创建 LUKS 设备机器有更多可用内存,您现在可能没有足够的内存。我们只讨论 RAM,在这种情况下不使用交换。

我建议重新创建 LUKS 设备,以--pbkdf pbkdf2切换到“旧”(LUKS1 中的默认设置)密钥派生函数 PBKDF2,该函数不使用额外的内存。或者,您也可以使用--pbkdf-memory <num>强制减少默认 Argon2i 的内存量。


Qua*_*odo 6

Vojtech Trefny 已经解释过,发生这种情况是因为 Argon2i 需要太多内存。事实上,来自man cryptsetup

对于 PBKDF2,仅适用时间成本(迭代次数)。对于Argon2i/id,还有内存成本(密钥派生过程中所需的内存)和并行成本(密钥派生过程中并行运行的线程数)。

但是,只要您能够访问具有足够内存1 的硬件,重新创建设备就显得有些过分了。

相反,使用具有足够内存的计算机,只需使用以下命令将密钥添加到加密设备中pbkdf2

cryptsetup luksAddKey -S 1 --pbkdf pbkdf2 /dev/sdxy
Run Code Online (Sandbox Code Playgroud)

假设密钥槽 1 是空闲的(您可以通过检查找到空闲密钥槽cryptsetup luksDump /dev/sdxy)。

然后,在功能较弱的计算机中,使用以下命令解锁设备

cryptsetup luksOpen -S 1 /dev/sdxy name
Run Code Online (Sandbox Code Playgroud)

-S 1是必要的,否则可能会尝试更昂贵的密钥,并且仍然会触发 OOM 杀手。

1:请记住,您始终可以保留一个带有最少外壳和核心实用程序的可启动 USB(Debian ISO 为我剪裁了它),并且您将能够在大多数计算机中启动它并访问您的加密卷。