cryptsetup mistakenly includes newline character in passphrase

"[email protected]" <[email protected]>
Newsgroups dev.linux.lists.cryptsetup
Message-ID <CACHosL8qEEToama-927w8JciczidoeSPFM_a-SF5zWEVZUabLQ@mail.gmail.com>
Hi cryptsetup/LUKS Team,

I noticed a potential bug in cryptsetup:

When feeding the passphrase via stdin, then cryptsetup includes the newline
character ('\n') in the passphrase.
This behavior contradicts the manual of cryptsetup:
Under title "NOTES ON PASSPHRASE PROCESSING FOR LUKS" it is written as
follows:
"From stdin: LUKS will read passphrases from stdin up to the first newline
character or the compiled-in maximum key file length."

I've written a script which reproduces the bug (attached, file
"commands_reproduce.sh"), executed it and provided its output (attached,
file "log.txt").

Please check this issue.

Best regards,
David.
log.txt (text/plain, 11.7 KB)
Format device with LUKS container:
# cryptsetup 2.4.3 processing "cryptsetup --verbose --debug --hash sha512 --iter-time=50 --key-size 256 --type=luks2 luksFormat /dev/sda5 -"
# Running command luksFormat.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /dev/sda5.
# Trying to open and read device /dev/sda5 with direct-io.
# Initialising device-mapper backend library.
WARNING: Device /dev/sda5 already contains a 'crypto_LUKS' superblock signature.
# STDIN descriptor passphrase entry requested.
# Crypto backend (OpenSSL 3.0.2 15 Mar 2022 [default][legacy]) initialized in cryptsetup library version 2.4.3.
# Detected kernel Linux 5.15.0-43-generic x86_64.
# PBKDF argon2id, time_ms 50 (iterations 0), max_memory_kb 1048576, parallel_threads 4.
Existing 'crypto_LUKS' superblock signature on device /dev/sda5 will be wiped.
Existing 'crypto_LUKS' superblock signature on device /dev/sda5 will be wiped.
# Formatting device /dev/sda5 as type LUKS2.
# Auto-detected optimal encryption sector size for device /dev/sda5 is 512 bytes.
# Topology: IO (512/0), offset = 0; Required alignment is 1048576 bytes.
# Checking if cipher aes-xts-plain64 is usable.
# Using userspace crypto wrapper to access keyslot area.
# Formatting LUKS2 with JSON metadata area 12288 bytes and keyslots area 16744448 bytes.
# Creating new digest 0 (pbkdf2).
# Setting PBKDF2 type key digest 0.
# Running pbkdf2(sha512) benchmark.
# PBKDF benchmark: memory cost = 0, iterations = 1724631, threads = 0 (took 19 ms)
# PBKDF benchmark: memory cost = 0, iterations = 1765279, threads = 0 (took 297 ms)
# PBKDF benchmark: memory cost = 0, iterations = 1774240, threads = 0 (took 591 ms)
# Benchmark returns pbkdf2(sha512) 1774240 iterations, 0 memory, 0 threads (for 256-bits key).
# Segment 0 assigned to digest 0.
# Wiping LUKS areas (0x000000 - 0x1000000) with zeroes.
# Wiping keyslots area (0x008000 - 0x1000000) with random data.
# Reusing open rw fd on device /dev/sda5
# Device size 115964116992, offset 16777216.
# Acquiring write lock for device /dev/sda5.
# Opening lock resource file /run/cryptsetup/L_8:5
# Verifying lock handle for /dev/sda5.
# Device /dev/sda5 WRITE lock taken.
# Trying to write LUKS2 header (16384 bytes) at offset 0.
# Reusing open rw fd on device /dev/sda5
# Checksum:ffa3de155faa7b6c391a287250c4ee9910c73e688815e906afa1b15c280e7f36 (in-memory)
# Trying to write LUKS2 header (16384 bytes) at offset 16384.
# Reusing open rw fd on device /dev/sda5
# Checksum:221fcd31672fb3c669910598eb77e9c0f7413a2708a187a3440c1026be868d07 (in-memory)
# Device /dev/sda5 WRITE lock released.
# Adding new keyslot -1 using volume key.
# Adding new keyslot -1 with volume key assigned to a crypt segment.
# Selected keyslot 0.
# Keyslot 0 assigned to digest 0.
# Trying to allocate LUKS2 keyslot 0.
# Found area 32768 -> 163840
# Running argon2id() benchmark.
# PBKDF benchmark: memory cost = 65536, iterations = 4, threads = 4 (took 57 ms)
# PBKDF benchmark: memory cost = 287438, iterations = 4, threads = 4 (took 240 ms)
# PBKDF benchmark: memory cost = 299414, iterations = 4, threads = 4 (took 249 ms)
# PBKDF benchmark: memory cost = 300616, iterations = 4, threads = 4 (took 249 ms)
# PBKDF benchmark: memory cost = 301823, iterations = 4, threads = 4 (took 249 ms)
# PBKDF benchmark: memory cost = 303035, iterations = 4, threads = 4 (took 252 ms)
# Benchmark returns argon2id() 4 iterations, 65536 memory, 4 threads (for 256-bits key).
# Calculating attributes for LUKS2 keyslot 0.
# Acquiring write lock for device /dev/sda5.
# Opening lock resource file /run/cryptsetup/L_8:5
# Verifying lock handle for /dev/sda5.
# Device /dev/sda5 WRITE lock taken.
# Checking context sequence id matches value stored on disk.
# Reusing open ro fd on device /dev/sda5
# Running keyslot key derivation.
# Updating keyslot area [0x8000].
# Reusing open rw fd on device /dev/sda5
# Device size 115964116992, offset 16777216.
# Device /dev/sda5 WRITE lock already held.
# Trying to write LUKS2 header (16384 bytes) at offset 0.
# Reusing open rw fd on device /dev/sda5
# Checksum:932f1402012b950c0209021ad63efa2bee0f6d4794465e28187b4cd39f349d09 (in-memory)
# Trying to write LUKS2 header (16384 bytes) at offset 16384.
# Reusing open rw fd on device /dev/sda5
# Checksum:6444e4480d67748d9fa3b3f636300cf9405cc7fa27727a02972e992e248eef0c (in-memory)
# Device /dev/sda5 WRITE lock released.
Key slot 0 created.
# Releasing crypt device /dev/sda5 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/sda5.
# Closing read write fd for /dev/sda5.
# Unlocking memory.
Command successful.



Try to open without a newline (should fail):
No key available with this passphrase.
# cryptsetup 2.4.3 processing "cryptsetup --verbose --debug --key-file - open /dev/sda5 debug_open"
# Running command open.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /dev/sda5.
# Trying to open and read device /dev/sda5 with direct-io.
# Initialising device-mapper backend library.
# Trying to load any crypt type from device /dev/sda5.
# Crypto backend (OpenSSL 3.0.2 15 Mar 2022 [default][legacy]) initialized in cryptsetup library version 2.4.3.
# Detected kernel Linux 5.15.0-43-generic x86_64.
# Loading LUKS2 header (repair disabled).
# Acquiring read lock for device /dev/sda5.
# Opening lock resource file /run/cryptsetup/L_8:5
# Verifying lock handle for /dev/sda5.
# Device /dev/sda5 READ lock taken.
# Trying to read primary LUKS2 header at offset 0x0.
# Opening locked device /dev/sda5
# Verifying locked device handle (bdev)
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:932f1402012b950c0209021ad63efa2bee0f6d4794465e28187b4cd39f349d09 (on-disk)
# Checksum:932f1402012b950c0209021ad63efa2bee0f6d4794465e28187b4cd39f349d09 (in-memory)
# Trying to read secondary LUKS2 header at offset 0x4000.
# Reusing open ro fd on device /dev/sda5
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:6444e4480d67748d9fa3b3f636300cf9405cc7fa27727a02972e992e248eef0c (on-disk)
# Checksum:6444e4480d67748d9fa3b3f636300cf9405cc7fa27727a02972e992e248eef0c (in-memory)
# Device size 115964116992, offset 16777216.
# Device /dev/sda5 READ lock released.
# PBKDF argon2id, time_ms 2000 (iterations 0), max_memory_kb 1048576, parallel_threads 4.
# Activating volume debug_open using token (any type) -1.
# dm version   [ opencount flush ]   [16384] (*1)
# dm versions   [ opencount flush ]   [16384] (*1)
# Detected dm-ioctl version 4.45.0.
# Detected dm-crypt version 1.23.0.
# Device-mapper backend running with UDEV support enabled.
# dm status debug_open  [ opencount noflush ]   [16384] (*1)
No usable token is available.
# STDIN descriptor passphrase entry requested.
# Activating volume debug_open [keyslot -1] using passphrase.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm status debug_open  [ opencount noflush ]   [16384] (*1)
# Keyslot 0 priority 1 != 2 (required), skipped.
# Trying to open LUKS2 keyslot 0.
# Running keyslot key derivation.
# Reading keyslot area [0x8000].
# Acquiring read lock for device /dev/sda5.
# Opening lock resource file /run/cryptsetup/L_8:5
# Verifying lock handle for /dev/sda5.
# Device /dev/sda5 READ lock taken.
# Reusing open ro fd on device /dev/sda5
# Device /dev/sda5 READ lock released.
# Verifying key from keyslot 0, digest 0.
# Digest 0 (pbkdf2) verify failed with -1.
# Releasing crypt device /dev/sda5 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/sda5.
# Unlocking memory.
Command failed with code -2 (no permission or bad passphrase).



Try to open with a newline (should succeed):
# cryptsetup 2.4.3 processing "cryptsetup --verbose --debug --key-file - open /dev/sda5 debug_open"
# Running command open.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating context for crypt device /dev/sda5.
# Trying to open and read device /dev/sda5 with direct-io.
# Initialising device-mapper backend library.
# Trying to load any crypt type from device /dev/sda5.
# Crypto backend (OpenSSL 3.0.2 15 Mar 2022 [default][legacy]) initialized in cryptsetup library version 2.4.3.
# Detected kernel Linux 5.15.0-43-generic x86_64.
# Loading LUKS2 header (repair disabled).
# Acquiring read lock for device /dev/sda5.
# Opening lock resource file /run/cryptsetup/L_8:5
# Verifying lock handle for /dev/sda5.
# Device /dev/sda5 READ lock taken.
# Trying to read primary LUKS2 header at offset 0x0.
# Opening locked device /dev/sda5
# Verifying locked device handle (bdev)
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:932f1402012b950c0209021ad63efa2bee0f6d4794465e28187b4cd39f349d09 (on-disk)
# Checksum:932f1402012b950c0209021ad63efa2bee0f6d4794465e28187b4cd39f349d09 (in-memory)
# Trying to read secondary LUKS2 header at offset 0x4000.
# Reusing open ro fd on device /dev/sda5
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:6444e4480d67748d9fa3b3f636300cf9405cc7fa27727a02972e992e248eef0c (on-disk)
# Checksum:6444e4480d67748d9fa3b3f636300cf9405cc7fa27727a02972e992e248eef0c (in-memory)
# Device size 115964116992, offset 16777216.
# Device /dev/sda5 READ lock released.
# PBKDF argon2id, time_ms 2000 (iterations 0), max_memory_kb 1048576, parallel_threads 4.
# Activating volume debug_open using token (any type) -1.
# dm version   [ opencount flush ]   [16384] (*1)
# dm versions   [ opencount flush ]   [16384] (*1)
# Detected dm-ioctl version 4.45.0.
# Detected dm-crypt version 1.23.0.
# Device-mapper backend running with UDEV support enabled.
# dm status debug_open  [ opencount noflush ]   [16384] (*1)
No usable token is available.
# STDIN descriptor passphrase entry requested.
# Activating volume debug_open [keyslot -1] using passphrase.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm status debug_open  [ opencount noflush ]   [16384] (*1)
# Keyslot 0 priority 1 != 2 (required), skipped.
# Trying to open LUKS2 keyslot 0.
# Running keyslot key derivation.
# Reading keyslot area [0x8000].
# Acquiring read lock for device /dev/sda5.
# Opening lock resource file /run/cryptsetup/L_8:5
# Verifying lock handle for /dev/sda5.
# Device /dev/sda5 READ lock taken.
# Reusing open ro fd on device /dev/sda5
# Device /dev/sda5 READ lock released.
# Verifying key from keyslot 0, digest 0.
# Loading key (32 bytes, type logon) in thread keyring.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm status debug_open  [ opencount noflush ]   [16384] (*1)
# Calculated device size is 226459648 sectors (RW), offset 32768.
# DM-UUID is CRYPT-LUKS2-cc3cebb890834b69955810730a1abc5d-debug_open
# Udev cookie 0xd4d962d (semid 2) created
# Udev cookie 0xd4d962d (semid 2) incremented to 1
# Udev cookie 0xd4d962d (semid 2) incremented to 2
# Udev cookie 0xd4d962d (semid 2) assigned to CREATE task(0) with flags DISABLE_LIBRARY_FALLBACK         (0x20)
# dm create debug_open CRYPT-LUKS2-cc3cebb890834b69955810730a1abc5d-debug_open [ opencount flush ]   [16384] (*1)
# dm reload   (253:0) [ opencount flush securedata ]   [16384] (*1)
# dm resume debug_open  [ opencount flush securedata ]   [16384] (*1)
# debug_open: Stacking NODE_ADD (253,0) 0:6 0660 [trust_udev]
# debug_open: Stacking NODE_READ_AHEAD 256 (flags=1)
# Udev cookie 0xd4d962d (semid 2) decremented to 1
# Udev cookie 0xd4d962d (semid 2) waiting for zero
# Udev cookie 0xd4d962d (semid 2) destroyed
# debug_open: Skipping NODE_ADD (253,0) 0:6 0660 [trust_udev]
# debug_open: Processing NODE_READ_AHEAD 256 (flags=1)
# debug_open (253:0): read ahead is 256
# debug_open: retaining kernel read ahead of 256 (requested 256)
Key slot 0 unlocked.
# Releasing crypt device /dev/sda5 context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/sda5.
# Unlocking memory.
Command successful.
commands_reproduce.sh (application/x-shellscript, 1.6 KB)
#!/usr/bin/env bash

#
# Reproduce the cryptsetup issue with newline (linefeed character ; i.e. '\n') in the passphrase.
#

# ---------

# Preparations:

# Have the script output (stdout + stderr) to be sent to a file
# while also being presented in the terminal.
LOG_DIR="."
script_log_filepath="${LOG_DIR}/log.txt"
# The following trick with "exec", i.e. ">(list)", uses bash's "Process Substitution".
# This trick leads to a race condition that may appear when program ends.
exec > >(tee "${script_log_filepath}") 2>&1
if [ ! $? -eq 0 ]; then
    echo "Redirection error happened. Quitting..."
    exit 2
fi

# ---------

# Actualy code which reproduce the issue:

DEVP="/dev/sda"

PASSPHRASE="123"
ITER_TIME=50 # Just to make it fast.
KEY_SIZE_BITS=256

cmd_cryptsetup_params+=(--verbose)
cmd_cryptsetup_params+=(--debug)
cmd_cryptsetup_params+=(--hash sha512)
cmd_cryptsetup_params+=(--iter-time=${ITER_TIME})
cmd_cryptsetup_params+=(--key-size ${KEY_SIZE_BITS})

echo "Format device with LUKS container:"
printf "%s\n" "${PASSPHRASE}" | cryptsetup "${cmd_cryptsetup_params[@]}" --type=luks2 luksFormat ${DEVP}5 -
echo -e "\n\n"

# The following fails to open:
echo "Try to open without a newline (should fail):"
printf "%s" "${PASSPHRASE}" | cryptsetup --verbose --debug --key-file - open ${DEVP}5 debug_open
echo -e "\n\n"

# The following successfully open:
echo "Try to open with a newline (should succeed):"
printf "%s\n" "${PASSPHRASE}" | cryptsetup --verbose --debug --key-file - open ${DEVP}5 debug_open


# Note: Use the following command to close the device:
# sudo cryptsetup --verbose --debug close debug_open
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.