cryptsetup:从文件读取密码时,luksOpen 中的验证是不确定的

cryptsetup:从文件读取密码时,luksOpen 中的验证是不确定的

我正在调试 cryptsetup 的奇怪行为:

假设文件中存储了正确的密码pw。我现在预计,--test-passphrase如果它作为标准输入传入,那么总是会成功(即不打印输出)。但事实证明它随机失败:

# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
# cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2 < pw
No key available with this passphrase.

我注意到了这一点,因为我在启动时多次无法解锁分区(在 GRUB 中)。首先,我以为我打错了,但现在我觉得这可能是 cryptsetup 中的一个错误。即使我复制粘贴了正确的密码,我也无法在以后一致地解锁它(不是在 GRUB 中)。

请注意,当我通过这种(大部分是等效的)方式传递它时,它也有所不同:

# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.
# cat pw | cryptsetup luksOpen --test-passphrase /dev/nvme0n1p2
No key available with this passphrase.

除了一次尝试外,所有尝试都失败了。而另一种方法更容易成功。这种行为对我来说是可以重现的:它总是更频繁地失败。

# cryptsetup --version
cryptsetup 2.6.1 flags: UDEV BLKID KEYRING KERNEL_CAPI

# cryptsetup luksDump /dev/nvme0n1p2
LUKS header information
Version:        2
Epoch:          5
Metadata area:  16384 [bytes]
Keyslots area:  16744448 [bytes]
UUID:           2372e472-ef96-428f-b971-f68fb0c35b63
Label:          (no label)
Subsystem:      (no subsystem)
Flags:          (no flags)

Data segments:
  0: crypt
    offset: 16777216 [bytes]
    length: (whole device)
    cipher: aes-xts-plain64
    sector: 512 [bytes]

Keyslots:
  0: luks2
    Key:        512 bits
    Priority:   normal
    Cipher:     aes-xts-plain64
    Cipher key: 512 bits
    PBKDF:      argon2id
    Time cost:  13
    Memory:     1048576
    Threads:    4
    Salt:       ea b0 88 ... 
                f3 f9 72 ... 
    AF stripes: 4000
    AF hash:    sha256
    Area offset:32768 [bytes]
    Area length:258048 [bytes]
    Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
    Hash:       sha256
    Iterations: 334367
    Salt:       f0 ac 44 ... 
                f3 6f d5 ... 
    Digest:     cd a8 ... 
                23 2a ... 

$ uname -a
Linux amd12 6.3.2-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 11 May 2023 16:40:42 +0000 x86_64 GNU/Linux

(OS: Arch Linux)

最终,我总是可以解锁,但我需要多次尝试,这很烦人。看起来验证码或读取输入的机制很不稳定。

我想知道这是否是一个已知问题(尽管我还没有发现任何相关信息)?如果不行的话有办法调试吗?不幸的是,我没有看到获得任何视觉反馈的选项(我认为,泄露密码长度被认为是一个安全缺陷)。

更新:刚刚意识到还有一个--debug选择。尽管成功和失败运行的输出在计算发生之前是相同的。调试日志中的所有标头和校验和都是相同的。

此外,它在 Linux Mint Live CD 上显示了与 cryptsetup 2.4.3 相同的行为。

答案1

@frostschutz 是正确的。事实证明,我机器上的内存在 Memtest86+ 运行中显示错误。

最可能的解释是计算成功或失败取决于正在使用 RAM 的哪一部分。 Argon2(现在是密钥派生的默认值)在计算过程中使用大量内存。

但这不是 cryptsetup 的错。现在,我再次测试了仅一个内存块,该内存块至少通过了一次 Memtest86+ 运行。它不再可重现。两个版本(< pwcat pw |)现在总是通过。

更新:我通过移除 RAM 插槽进行了更多测试。有趣的是,它适用于单独的插槽,但组合起来就变得不可靠。机器本身是新的,但我看到了XMP(极限内存配置文件)已启用。据我了解,这在新硬件上是合理的安全默认设置,但在我的机器上它似乎导致了问题。禁用后,现在可以使用了。

也许他们应该在 memtest86+ 中包含 Argon2。在我的系统上,检测内存问题非常有用。

相关内容