3

When i execute the cryptsetup command, it responds with a command line output - "Enter any existing passphrase:".

I want to read this from console into my script and pass the passphrase from the script itself since i am decrypting many partitions and asking user to enter passphrase every time is not feasible.

Command execution:

cryptsetup luksAddKey /dev/LUKS_device_name /etc/keyfile

Enter any existing passphrase:

Appreciate any help on this.

1 Answer 1

0

My answer relies on the needed Linux kernel feature CONFIG_KEYS.

There is a keyscript command intended for what you want available there:

https://github.com/gebi/keyctl_keyscript

It uses the Kernel Key Retention Service (which has been around for a long time) with the command keyctl to ask and temporarily store the passphrase in memory if not already found, and use it for any related invocations of multiple cryptsetup commands. It's probably included in most distributions (eg: on Debian, the package cryptsetup has it as /lib/cryptsetup/scripts/decrypt_keyctl ).

Normally you'd use it integrated within the distribution and configured in an /etc/crypttab file like the given example:

test1   /dev/sda1    test_pw         luks,keyscript=decrypt_keyctl
test2   /dev/sda2    test_pw         luks,keyscript=decrypt_keyctl
test3   /dev/sda3    test_other_pw   luks,keyscript=decrypt_keyctl

Which would trigger asking a passphrase for test1, reuse the answer on test2 (because its key id is the same as the previous one and the passphrase was already given) and ask a new question for test3.

Now if you want to use this tool directly, not along system's integration, you can run the command and pipe it directly to cryptsetup.

UPDATE: Put a complete full example that can be reproduced except for the few values which will depend on environment (here /dev/loop0 and 969933847):

Create a test LUKS device from a fake disk. Be very careful that losetup actually returned /dev/loop0 or abort this example:

# dd if=/dev/zero seek=$(( 2 ** 30 - 1 )) bs=1 count=1 of=/tmp/block.img
1+0 records in
1+0 records out
1 byte copied, 6.0997e-05 s, 16.4 kB/s
# losetup --find --show /tmp/block.img 
/dev/loop0
# echo -n goodpass | cryptsetup luksFormat /dev/loop0
# cryptsetup luksDump /dev/loop0
LUKS header information for /dev/loop0

Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha256
Payload offset: 4096
MK bits:        256
MK digest:      4e 98 86 0b bf 63 3f 68 08 f5 cc 4f 61 ec 8c 19 71 c3 2a 33 
MK salt:        dc ce 7b a1 56 79 70 c5 02 ad ec 4c 85 c1 6f c1 
                af 50 f3 8c 89 b9 a9 3a 02 62 5c 2d 3f 7a 9d 52 
MK iterations:  312000
UUID:           61a3a890-9564-4c98-866a-1216474b839e

Key Slot 0: ENABLED
    Iterations:             2467468
    Salt:                   04 82 b5 b7 0b 90 e4 62 45 96 e3 c3 ef ba 6d 66 
                            1d 93 6b e0 e9 03 40 3d 39 b9 fe 2c 6f 9e 46 e4 
    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

Now try operations on it using decrypt_keyctl. The prassphrase is as previously set: goodpass. Note that /etc/crypttab is not used nor needed for this example run directly (on Debian 9's modified version, here with two variables to avoid an harmless warning and still print a cosmetic "example" when used outside of the expected environment):

# echo -n securepass > /tmp/newkey
# export CRYPTTAB_TRIED=0 CRYPTTAB_SOURCE=example
# /lib/cryptsetup/scripts/decrypt_keyctl lazy | cryptsetup luksOpen /dev/loop0 test1
Caching passphrase for example:  ********
# cryptsetup close test1
# cryptsetup status test1
/dev/mapper/test1 is inactive.
# /lib/cryptsetup/scripts/decrypt_keyctl lazy | cryptsetup luksAddKey /dev/loop0 /tmp/newkey
Using cached passphrase for example.
# /lib/cryptsetup/scripts/decrypt_keyctl lazy | cryptsetup luksOpen /dev/loop0 test1
Using cached passphrase for example.
# cryptsetup status test1
/dev/mapper/test1 is active.
  type:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 256 bits
  device:  /dev/loop0
  loop:    /tmp/block.img
  offset:  4096 sectors
  size:    2093056 sectors
  mode:    read/write

Of course you could even use directly keyctl, here's a following (really bad) example still using the previous luks device, that can be done right after:

# cryptsetup close test1
# echo -n goodpass | keyctl padd user lazy @u
969933847
# keyctl timeout 969933847 120
# keyctl pipe 969933847 | cryptsetup luksOpen /dev/loop0 test1 && echo OK
OK
# keyctl pipe 969933847 | cryptsetup luksAddKey /dev/loop0 /tmp/newkey && echo OK
OK
# keyctl clear @u

Cleanup:

# cryptsetup close test1
# losetup -d /dev/loop0    
# rm /tmp/block.img
3
  • Thanks for the reply but for some reason it doesnt work for me- [root@vsr-a etc]# export CRYPTTAB_TRIED=0 CRYPTTAB_SOURCE=xyz [root@vsr-a etc]# /lib/cryptsetup/scripts/decrypt_keyctl lazy | cryptsetup luksOpen /dev/md199p9 xyz Device xyz already exists. [root@vsr-a scripts]# cat /etc/crypttab xyz UUID=abc test_pw: luks,keyscript=decrypt_keyctl Mar 27, 2019 at 6:55
  • cryptsetup tells you you already opened /dev/md199p9 . close it first (if it's not in use of course) or do an other operation (eg luksAddKey). In crypttab for each line the first 2 parameters are of course always different, the common parameter is the 3rd, and can be anything (its : makes no sense here)
    – A.B
    Mar 27, 2019 at 7:17
  • I revised my answer to have a full example that you should try
    – A.B
    Mar 27, 2019 at 7:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .