Open LUKS2 encrypted volume on a low memory device.
There are those rare situations when you cannot open LUKS encrypted volume on a low memory device.
$ sudo cryptsetup luksOpen /dev/sda1 decrypted_sda1
Enter passphrase for /dev/sda1: Killed
The process is killed by the OOM killer.
$ dmesg -T | tail
[Tue May 4 20:18:51 2021] [ 2688] 33 2688 1779 207 14336 149 0 nginx [Tue May 4 20:18:51 2021] [ 2689] 33 2689 1779 207 14336 149 0 nginx [Tue May 4 20:18:51 2021] [ 2690] 33 2690 1779 207 12288 149 0 nginx [Tue May 4 20:18:51 2021] [ 2700] 0 2700 1294 494 14336 60 0 cron [Tue May 4 20:18:51 2021] [ 2883] 107 2883 181125 0 176128 16069 0 mysqld [Tue May 4 20:18:51 2021] [ 3030] 0 3030 1650 495 16384 81 0 sudo [Tue May 4 20:18:51 2021] [ 3031] 0 3031 264642 232106 935936 0 0 cryptsetup [Tue May 4 20:18:51 2021] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/,task=cryptsetup,pid=3031,uid=0 [Tue May 4 20:18:51 2021] Out of memory: Killed process 3031 (cryptsetup) total-vm:1058568kB, anon-rss:920420kB, file-rss:8004kB, shmem-rss:0kB, UID:0 pgtables:914kB oom_score_adj:0 [Tue May 4 20:18:51 2021] oom_reaper: reaped process 3031 (cryptsetup), now anon-rss:920428kB, file-rss:7992kB, shmem-rss:0kB
You will likely encounter this issue when using LUKS2 as LUKS1 uses PBKDF2 as key derivation function (only time cost), but LUKS2 uses Argon2i/Argon2id (time, memory, and parallel cost).
Sample LUKS2 header version 2.
$ sudo cryptsetup luksDump /dev/sda1
LUKS header information Version: 2 Epoch: 5 Metadata area: 16384 [bytes] Keyslots area: 16744448 [bytes] UUID: 0e17b44c-a9af-4da1-8f98-062552e1df7a 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: argon2i Time cost: 5 Memory: 1048576 Threads: 4 Salt: af b0 98 7d a1 07 a4 17 d9 78 d6 13 c2 61 14 36 e7 51 ea 90 21 cb 29 62 d8 9b 45 78 90 02 b5 c0 AF stripes: 4000 AF hash: sha256 Area offset:32768 [bytes] Area length:258048 [bytes] Digest ID: 0 6: luks2 Key: 512 bits Priority: normal Cipher: aes-xts-plain64 Cipher key: 512 bits PBKDF: pbkdf2 Hash: sha256 Iterations: 1836384 Salt: 6d 99 0b f4 eb 5e 81 12 2b 13 a5 67 0d 47 10 88 f5 66 da 00 bd 33 9b f6 cf 29 ee ab fe a7 14 c9 AF stripes: 4000 AF hash: sha256 Area offset:290816 [bytes] Area length:258048 [bytes] Digest ID: 0 7: luks2 Key: 512 bits Priority: normal Cipher: aes-xts-plain64 Cipher key: 512 bits PBKDF: pbkdf2 Hash: sha256 Iterations: 1859176 Salt: 25 de 5c 85 7d a2 39 77 f9 f9 74 89 ea 4d 22 ce 36 16 2c 98 24 86 fb 9e a1 fc a1 17 cd 6b 72 ac AF stripes: 4000 AF hash: sha256 Area offset:548864 [bytes] Area length:258048 [bytes] Digest ID: 0 Tokens: Digests: 0: pbkdf2 Hash: sha256 Iterations: 116819 Salt: ce 39 26 63 7c 48 10 3f 16 ee a1 c2 7b 0c 94 b0 ee d3 f1 38 bc da 9e 78 9d 68 59 53 3c 04 1a bb Digest: db 65 ad 6a 80 fc 5f 42 ad 9c 1e ee 39 5a 8d 33 b4 ad 6e 50 c9 fc 99 45 27 75 91 95 96 c8 9e c9
Sample LUKS2 header version 1.
$ sudo cryptsetup luksDump /dev/sdd1
LUKS header information for /dev/sdd1 Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha256 Payload offset: 4096 MK bits: 512 MK digest: 5c ae 6f 4e 12 15 59 70 24 bf c9 84 82 c6 01 f1 f7 9a d4 77 MK salt: 65 56 a3 83 7e 52 eb 7f ae b0 cb 40 2b 65 79 b7 81 eb 80 3b 13 fa b6 28 8e 29 7d 33 ca 66 0b b5 MK iterations: 107436 UUID: a0bad006-a567-4f5f-83c2-5c86ba50e5df Key Slot 0: ENABLED Iterations: 1771242 Salt: 9d f7 31 82 eb 41 f9 cc 0f 53 42 46 9e 30 d7 0b 6e 7b e6 f8 bd a1 bb 41 98 d4 41 17 78 4c 84 8e 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
There are multiple solutions as you can convert keyslot to new pbkdf parameters, convert LUKS header version 2 to LUKS header version 1, and add new key using PBKDF2 as a key derivation function.
The easiest solution is to add a new key or password. Do it on a slightly more powerful machine.
Create a new key.
$ dd if=/dev/urandom of=secret.key bs=512 count=1
1+0 records in 1+0 records out 512 bytes copied, 0,000272616 s, 1,9 MB/s
Add it to the unused keyslot.
$ sudo cryptsetup luksAddKey --key-slot 7 --pbkdf pbkdf2 /dev/sda1 secret.key
Enter any existing passphrase: **********
Now you can use this key to open the LUKS device in low memory conditions.
$ sudo cryptsetup luksOpen /dev/sda1 --key-slot 7 --key-file ~/.secret.key decrypted_sda1
It works!