#3361 Issue open: Artix Linux: LUKS2 hash is not correctly recognized when the cryptdevice contains a key-slot with pbkdf2

Labels: enhancement

castilma opened issue at 2024-12-11 13:17:

  • ReaR version ("/usr/sbin/rear -V"):
    Relax-and-Recover 2.7 / Git

  • OS version ("cat /etc/os-release" or "lsb_release -a" or "cat /etc/rear/os.conf"):

NAME="Artix Linux"
PRETTY_NAME="Artix Linux"
ID=artix
BUILD_ID=rolling
ANSI_COLOR="0;36"
HOME_URL="https://www.artixlinux.org/"
DOCUMENTATION_URL="https://wiki.artixlinux.org/"
SUPPORT_URL="https://forum.artixlinux.org/"
BUG_REPORT_URL="https://bugs.artixlinux.org/"
PRIVACY_POLICY_URL="https://terms.artixlinux.org/docs/privacy-policy/"
LOGO=artixlinux-logo
  • ReaR configuration files ("cat /etc/rear/site.conf" and/or "cat /etc/rear/local.conf"):
OUTPUT=RAWDISK
#OUTPUT_URL=

BACKUP=REQUESTRESTORE

REQUIRED_PROGS+=( restic )

KEYMAP="de-neo"
BOOTLOADER="GRUB2"
  • Hardware vendor/product (PC or PowerNV BareMetal or ARM) or VM (KVM guest or PowerVM LPAR):
    PC

  • System architecture (x86 compatible or PPC64/PPC64LE or what exact ARM device):
    x86_64

  • Firmware (BIOS or UEFI or Open Firmware) and bootloader (GRUB or ELILO or Petitboot):
    UEFI, GRUB

  • Storage (local disk or SSD) and/or SAN (FC or iSCSI or FCoE) and/or multipath (DM or NVMe):
    SSD

  • Storage layout ("lsblk -ipo NAME,KNAME,PKNAME,TRAN,TYPE,FSTYPE,LABEL,SIZE,MOUNTPOINT"):

NAME KNAME     PKNAME    TRAN   TYPE  FSTYPE LABEL   SIZE MOUNTPOINT
/dev/sda
|    /dev/sda            sata   disk               447,1G 
|-/dev/sda1
|    /dev/sda1 /dev/sda         part                 200M /efi
|-/dev/sda2
|    /dev/sda2 /dev/sda         part                   1M 
`-/dev/sda3
  |  /dev/sda3 /dev/sda         part               446,9G 
  `-/dev/mapper/lvmSystem
    |  /dev/dm-0 /dev/sda3        crypt              446,9G 
    |-/dev/mapper/lvmSystem-volSwap
    |  /dev/dm-1 /dev/dm-0        lvm                    8G [SWAP]
    `-/dev/mapper/lvmSystem-volRoot
       /dev/dm-2 /dev/dm-0        lvm                438,9G /
/dev/sr0
     /dev/sr0            sata   rom                  7,8G
  • Description of the issue (ideally so that others can reproduce it):

If a key-slot uses the key derivation function pbkdf2, luksDump outputs a Hash: line for that entry. This
breaks the 'hash' checking code in 260_crypt_layout.sh, because multiple Hash: lines exist and the test argument is not quoted:
https://github.com/rear/rear/blob/40cbaaf50b689b73be77b9a12b4321a787db6681/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh#L118

Like in line 87, the extraction should probably just choose one line, but not always the first one! Right now it accepts all lines:
https://github.com/rear/rear/blob/40cbaaf50b689b73be77b9a12b4321a787db6681/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh#L88

Reproduce like this:

$ head -c 10M /dev/zero >img.iso
$ cryptsetup luksFormat --type luks1 img.iso 
$ cryptsetup convert /tmp/img.iso  --type luks2
$ cryptsetup luksDump /tmp/img.iso 
LUKS header information
Version:        2
Epoch:          2
Metadata area:  16384 [bytes]
Keyslots area:  2064384 [bytes]
UUID:           f100df28-dd7b-4fd4-890f-da0115a7e079
Label:          (no label)
Subsystem:      (no subsystem)
Flags:          (no flags)

Data segments:
  0: crypt
    offset: 2097152 [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:      pbkdf2
    Hash:       sha256
    Iterations: 1222116
    Salt:       ae d6 86 ce 59 8d 45 a1 83 12 e6 1e 76 df ca 20 
                a2 f7 0e cb f5 18 15 b0 fd bc d1 14 54 f3 5a a1 
    AF stripes: 4000
    AF hash:    sha256
    Area offset:32768 [bytes]
    Area length:258048 [bytes]
    Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
    Hash:       sha256
    Iterations: 76293
    Salt:       d5 86 16 6c 54 2c 62 da 36 b4 82 31 84 67 9d f5 
                6f 3c e5 a0 d3 82 33 32 54 bd d0 0d ec 89 ac b0 
    Digest:     75 7b b1 29 cd 6b 14 98 22 26 72 1c c4 ca a5 fd 
                db 3e fd a3

Note the new 'Hash:' line in the first key slot. I believe rear is interested in the second one under Digests:.

Background: I upgraded my LUKS1 device to LUKS2 (after reading this PSA), but did not follow the last step to update the pbkdf to argon, which I is the default for luks2 devices. So I ended up having a keyslot with the 'pbkdf2', which should be pretty rare with luks2.

  • Workaround, if any:
    Update the keyslot by running $ cryptsetup luksConvertKey <DEVICE> --pbkdf argon2id with the corresponding password.

jsmeix commented at 2024-12-11 14:27:

@castilma
did you get some

"No 'hash' value for LUKS.. volume ..."

message on your terminal?
If at all you would have got such a message only
if you did run "rear mkbackup/mkrescue" in verbose mode.

As far as I see in its comments the current code in
layout/save/GNU/Linux/260_crypt_layout.sh
https://github.com/rear/rear/blob/master/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh
seems to work as intended

    79          # More than one keyslot may be defined - use key_size from the first slot.
    80          # Depending on the version the "cryptsetup luksDump" command outputs the key_size value
    81          # as a line like
    82          #         Key:        512 bits
    83          # and/or as a line like
    84          #         Cipher key: 512 bits
    85          # cf. https://github.com/rear/rear/pull/2504#issuecomment-718729198 and subsequent comments
    86          # so we grep for both lines but use only the first match from the first slot:
    87          key_size=$( grep -E -m 1 "Key:|Cipher key:" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+) bits$/\1/' )
    88          hash=$( grep "Hash" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
...
   102      # Using plain test to ensure a value is a single non empty and non blank word
   103      # without quoting because test " " would return zero exit code
   104      # cf. "Beware of the emptiness" in https://github.com/rear/rear/wiki/Coding-Style
...
   118      if ! test $hash ; then

which does not mean that the current code
will work for all possible cases
so the current code may need to be enhanced
to error out if a mandatory condition is not fulfilled
or to even also work for more special cases like this one.

Perhaps in current code

   118      if ! test $hash ; then
   119          LogPrint "No 'hash' value for LUKS$version volume $target_name in $source_device"
   120      fi

LogPrint should be at least LogPrintError or even Error
but right now I don't know if a hash value is mandatory.

castilma commented at 2024-12-11 19:22:

Yes, I got some of these
"No 'hash' value for LUKS.. volume ..." lines. (I think it was with -v passed.)


[Export of Github issue for rear/rear.]