Skip to content

Tomb 2.9.0 as root with smartcard [Bug? + Workaround] #449

@so-rose

Description

@so-rose

A little background first. I'm using Secure Boot, which requires one to sign kernel modules with a user-generated, firmware-enrolled key. Anybody with this key can theoretically execute kernel-level code. Therefore, I'm attempting to use tomb to make these keys inaccessible without a GPG private key, stored on a piece of hardware (Yubikey).

This is my setup for running tomb:

  • On Debian 11 (uname -a: Linux <> 5.10.0-18-amd64 #1 SMP Debian 5.10.140-1 (2022-09-02) x86_64 GNU/Linux)
  • Exclusively as root (Secure Boot kernel module signing keys shouldn't touch non-root users)
  • With GPG private keys on a smartcard (only configured for the primary user)
  • At version 2.9 (latest in Debian repo)

I'm running the following commands as root, with no preexisting /root/.gnupg:

gpg --recv-keys $KEY_ID  ## import the tomb's owner + initialize /root/.gnupg

tomb dig -s 10 /root/mok.tomb
tomb forge /root/mok.tomb.key -gr $KEY_ID
tomb lock /root/mok.tomb -k /root/mok.tomb.key -gr $KEY_ID

#...open the tomb and use it!

The Problem

Running a similar script (s/root/$HOME/g) as a normal user works perfectly: The GUI pinentry shows, all is well.

As root, however, tomb lock fails insisting that there's no valid password (<> is redaction):

$ tomb lock /root/mok.tomb -k /root/mok.tomb.key -gr $KEY_ID -D
tomb  .  Locking using cipher: aes-xts-plain64
tomb [D] no password needed, using GPG key
tomb [D] get_lukskey
...
tomb [D] [GNUPG:] ENC_TO <> 1 0
tomb [D] [GNUPG:] KEY_CONSIDERED $KEY_ID 0
tomb [D] [GNUPG:] PINENTRY_LAUNCHED 140666 gnome3:curses 1.1.0 - xterm-kitty :0
tomb [D] [GNUPG:] KEY_CONSIDERED <> 0
tomb [D] gpg: encrypted with 4096-bit RSA key, ID $KEY_ID, created <>
tomb [D]       "<> <>"
tomb [D] gpg: public key decryption failed: Inappropriate ioctl for device
tomb [D] [GNUPG:] ERROR pkdecrypt_failed 83918950
tomb [D] [GNUPG:] BEGIN_DECRYPTION
tomb [D] [GNUPG:] DECRYPTION_FAILED
tomb [D] gpg: decryption failed: No secret key
tomb [D] [GNUPG:] END_DECRYPTION
tomb [D] get_lukskey returns 1
tomb [E] No valid password supplied.

It seems like gpg can't find anywhere to launch its pinentry. I observed:

  • The pinentry never launches. Neither in the terminal or GUI. Switching pinentry to point at pinentry-tty also doesn't help. This makes this problem distinct from the solved Unable to lock tomb using GPG #251.
  • Switching pinentry out to point to pinentry-tty (using update-alternatives) does has two effects:
    • The error Inappropriate ioctl for device is switched out for Invalid IPC response.
    • gnome3:curses alone is switched out for tty.

All in all, it seems like gpg doesn't know how to launch the pinentry, and thus just fails. tomb gets no secret to unlock the key with, and thus - no tomb ☹️

The Workaround

I noticed that the end of gpg_decrypt was where the critical gpg invocation was in the locking/opening procedure:

https://github.com/dyne/Tomb/blob/f35ad11e3f5b29fd9b441a3111cc7a0c097036b1/tomb#L1118-L1121

As it seemed like the pinentry-mode was an issue. I tried setting /root/.gnupg/gpg.conf after reading things like https://superuser.com/questions/520980/how-to-force-gpg-to-use-console-mode-pinentry-to-prompt-for-passwords, but this didn't seem to get picked up on.

Finally, because of answers like https://stackoverflow.com/questions/18123918/why-is-gpg-not-working-even-with-pinentry-installed, I tried adding --pinentry-mode loopback:

TOMBSECRET=`print - "$gpgpass" | \
		gpg --decrypt ${gpgpopt[@]} \
			--status-fd 2 --no-mdc-warning --no-permission-warning \
			--no-secmem-warning --pinentry-mode loopback 2> $tmpres`

Now, when I run the same command as root, it works!

$ tomb lock /root/mok.tomb -k /root/mok.tomb.key -gr $KEY_ID -D
tomb  .  Locking using cipher: aes-xts-plain64
tomb [D] no password needed, using GPG key
tomb [D] get_lukskey
tomb [D] Created tempfile: /tmp/14336175871231220299
Enter Passphrase: 

Again, it's curious that it still doesn't call the pinentry. This also breaks tomb when used as a non-root user.

Patch

If I understood the problem better, I'd be happy to suggest a PR. Perhaps a CLI option to explicitly turn on loopback pinentry? For now, I just have a patch (works on the Debian 11 version of tomb; I haven't tested upstream. It should be easy enough to modify the line number 1123 below to work on any tomb install)

tomb-loopback.patch

1123c1123
< 			--no-secmem-warning 2> $tmpres`
---
> 			--no-secmem-warning --pinentry-mode loopback 2> $tmpres`

used with:

patch /usr/bin/tomb < tomb-loopback.patch       ## Apply the patch
patch -R /usr/bin/tomb < tomb-loopback.patch   ## Remove the patch

Whenever I need to run tomb as root, I just wrap it in the patch:

gpg --recv-keys $KEY_ID  ## import the tomb's owner + initialize /root/.gnupg

patch /usr/bin/tomb < tomb-loopback.patch  ## A trap could make this more reliable
    tomb dig -s 10 /root/mok.tomb
    tomb forge /root/mok.tomb.key -gr $KEY_ID
    tomb lock /root/mok.tomb -k /root/mok.tomb.key -gr $KEY_ID
    
    tomb open /root/mok.tomb -k /root/mok.tomb.key -g -p
patch -R /usr/bin/tomb < tomb-loopback.patch

#...add root:root owned secrets to the tomb (courtesy -p).

When actually signing kernel modules via DKMS, I just modified /etc/dkms/sign_helper.sh to patch tomb, open mok.tomb (with GPG and -p, to avoid chowning files to a user calling via sudo), sign, tomb slam and unpatch tomb.

Thus, it's been achieved that no kernel modules can be signed without the presence of the smartcard w/the GPG private key 😄

System Info

Here's tomb -v:

  Tomb 2.9.0 - a strong and gentle undertaker for your secrets

   Copyright (C) 2007-2021 Dyne.org Foundation, License GNU GPL v3+
   This is free software: you are free to change and redistribute it
   For the latest sourcecode go to <http://dyne.org/software/tomb>

   This source code is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   When in need please refer to <http://dyne.org/support>.

  System utils:

No $DBUS_SESSION_BUS_ADDRESS found, falling back to curses
gpg: WARNING: unsafe ownership on homedir '/home/sofus/.gnupg'
gpg: WARNING: unsafe ownership on homedir '/home/sofus/.gnupg'
  zsh 5.8 (x86_64-debian-linux-gnu)
  Sudo version 1.9.5p2
  cryptsetup 2.3.7
  pinentry-gnome3 (pinentry) 1.1.0
  findmnt from util-linux 2.36.1
  gpg (GnuPG) 2.2.27 - key forging algorithms (GnuPG symmetric ciphers):
  IDEA 3DES CAST5 BLOWFISH AES AES192 AES256 TWOFISH CAMELLIA128 CAMELLIA192 CAMELLIA256

  Optional utils:

  /usr/bin/gettext
  dcfldd not found
  /usr/bin/shred
  steghide not found
  /usr/sbin/resize2fs
  /usr/libexec/tomb/tomb-kdb-pbkdf2
  /usr/bin/qrencode
  swish-e not found
  unoconv not found
  /usr/bin/lsof

Metadata

Metadata

Assignees

Labels

enhancementAn issue to improve current behavior

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions