Unlock LUKS with a touch screen/on-screen keyboard

Hello! This is my first question here - well, that might indicate that Garuda works really fine. But I finally run into an issue I failed to solve myself. If this is in the wrong catecory and should be in "Unsuppored Software (AUR & other)" feel free to move it there (if possible).

I got a new detachable 2-in-1 device (Shift13mi) with a touch screen and a Bluetooth keyboard.

I installed Garuda (Garuda KDE Dr460nized) with full disk encryption (FDE).

Now I have got the problem that I always need an USB keyboard to decrypt LUKS.

It would be nice if I could use the touch screen with an on-screen keyboard/virtual keyboard like "osk-sdl" to enter the passphrase.

So I installed "osk-sdl" from AUR and read the additional instructions from GitHub - ShapeShifter499/osk-sdl_arch: Getting osk-sdl working to help decrypt tablets and other touchscreen enabled devices running x86_64 bit Arch Linux as well. So I edited the HOOKS line in /etc/mkinitcpio.conf:

HOOKS="base udev autodetect modconf block keyboard keymap consolefont osk-sdl plymouth encrypt openswap resume filesystems grub-btrfs-overlayfs"

(I also added hid_multitouch to MODULES in order to get the touch screen running)

And I did a
sudo mkinitcpio -P
to update the initramfs.

Then I ideed get an the onscreen keyboard (OSK) - but only after Grub. But the LUKS decryption is before grub.

I also tested different positions in the HOOKS line (beween udev and filesystem), which always lead to the same result.

Has anyone an idea how to get an OSK for LUKS decryption in that early stage of the boot process?
Is /etc/mkinitcpio.conf even the right place to include that? It seems that everything I include in the HOOKS line works only after LUKS encryption.

And additionally: Might there be a way to get a bluetooth keyboard running for LUKS encryption? (I already tried mkinitcpio-bluetooth and mkinitcpio-wifi; it seems the BT controller is bundled with the wifi controller.)

Thanks in advance for any support.

My output from garuda-inxi:

  Kernel: 6.0.2-zen1-1-zen arch: x86_64 bits: 64 compiler: gcc v: 12.2.0
    parameters: BOOT_IMAGE=/@/boot/vmlinuz-linux-zen root=UUID=605283d8-010b-46a7-941f-2b47ba1f14e7
    rw [email protected] quiet
    root=/dev/mapper/luks-7d3d3b17-e19b-4057-8fb6-3bcbc8fada45 quiet splash
    rd.udev.log_priority=3 vt.global_cursor_default=0
    resume=/dev/mapper/luks-47fbec8a-e654-4427-a68c-8d7057c7e828 loglevel=3
  Console: pty pts/1 DM: SDDM Distro: Garuda Linux base: Arch Linux
  Type: Detachable System: SHIFT product: SHIFT13mi v: N/A serial: <filter>
  Mobo: SHIFT model: SHIFT13mi-pcb v: B5 serial: <filter> UEFI: American Megatrends LLC.
    v: 5.19 date: 03/05/2022
  ID-1: BAT0 charge: 49.8 Wh (92.4%) condition: 53.9/53.9 Wh (100.0%) volts: 12.7 min: 11.6
    model: Intel SR 1 SR Real Battery type: Unknown serial: <filter> status: discharging
  Info: model: 11th Gen Intel Core i5-1135G7 socket: U3E1 bits: 64 type: MT MCP arch: Tiger Lake
    gen: core 11 level: v4 note: check built: 2020 process: Intel 10nm family: 6
    model-id: 0x8C (140) stepping: 1 microcode: 0xA4
  Topology: cpus: 1x cores: 4 tpc: 2 threads: 8 smt: enabled cache: L1: 320 KiB desc: d-4x48
    KiB; i-4x32 KiB L2: 5 MiB desc: 4x1.2 MiB L3: 8 MiB desc: 1x8 MiB
  Speed (MHz): avg: 1802 high: 2400 min/max: 400/4200 base/boost: 2400/4200 scaling:
    driver: intel_pstate governor: powersave volts: 0.7 V ext-clock: 100 MHz cores: 1: 766 2: 2400
    3: 2400 4: 2400 5: 2400 6: 2400 7: 982 8: 668 bogomips: 38707
  Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx
  Type: itlb_multihit status: Not affected
  Type: l1tf status: Not affected
  Type: mds status: Not affected
  Type: meltdown status: Not affected
  Type: mmio_stale_data status: Not affected
  Type: retbleed status: Not affected
  Type: spec_store_bypass mitigation: Speculative Store Bypass disabled via prctl
  Type: spectre_v1 mitigation: usercopy/swapgs barriers and __user pointer sanitization
  Type: spectre_v2 mitigation: Enhanced IBRS, IBPB: conditional, RSB filling, PBRSB-eIBRS: SW
  Type: srbds status: Not affected
  Type: tsx_async_abort status: Not affected
  Device-1: Intel TigerLake-LP GT2 [Iris Xe Graphics] driver: i915 v: kernel arch: Gen-12.1
    process: Intel 10nm built: 2020-21 ports: active: eDP-1 empty: DP-1, DP-2, DP-3, DP-4, DP-5,
    HDMI-A-1 bus-ID: 00:02.0 chip-ID: 8086:9a49 class-ID: 0300
  Device-2: Orbbec 3D USB 2.0 Camera type: USB driver: snd-usb-audio,uvcvideo bus-ID: 3-5:2
    chip-ID: 2bc5:051e class-ID: 0102 serial: <filter>
  Display: x11 server: X.org v: with: Xwayland v: 22.1.4 compositor: kwin_x11 driver:
    X: loaded: modesetting alternate: fbdev,intel,vesa dri: iris gpu: i915 tty: 153x29
  Monitor-1: eDP-1 model: BOE Display 0x08dd built: 2019 res: 1920x1080 dpi: 166 gamma: 1.2
    size: 294x165mm (11.57x6.5") diag: 337mm (13.3") ratio: 16:9 modes: 1920x1080
  Message: GL data unavailable in console for root.
  Device-1: Intel Tiger Lake-LP Smart Sound Audio driver: snd_hda_intel v: kernel bus-ID: 3-5:2
    alternate: snd_sof_pci_intel_tgl chip-ID: 2bc5:051e bus-ID: 00:1f.3 class-ID: 0102
    chip-ID: 8086:a0c8 class-ID: 0403 serial: <filter>
  Device-2: Orbbec 3D USB 2.0 Camera type: USB driver: snd-usb-audio,uvcvideo
  Sound API: ALSA v: k6.0.2-zen1-1-zen running: yes
  Sound Server-1: PulseAudio v: 16.1 running: no
  Sound Server-2: PipeWire v: 0.3.59 running: yes
  Device-1: Intel Wi-Fi 6 AX200 driver: iwlwifi v: kernel pcie: gen: 2 speed: 5 GT/s lanes: 1
    bus-ID: ad:00.0 chip-ID: 8086:2723 class-ID: 0280
  IF: wlp173s0 state: up mac: <filter>
  IF-ID-1: anbox0 state: down mac: <filter>
  Device-1: Intel AX200 Bluetooth type: USB driver: btusb v: 0.8 bus-ID: 3-10:5
    chip-ID: 8087:0029 class-ID: e001
  Report: bt-adapter ID: hci0 rfk-id: 0 state: up address: <filter>
  Local Storage: total: 953.87 GiB used: 265.09 GiB (27.8%)
  ID-1: /dev/nvme0n1 maj-min: 259:0 vendor: Lexar model: SSD NM6A1 1TB size: 953.87 GiB
    block-size: physical: 512 B logical: 512 B speed: 31.6 Gb/s lanes: 4 type: SSD serial: <filter>
    rev: V1.25D temp: 27.9 C scheme: GPT
  SMART: yes health: PASSED on: 34 hrs cycles: 76 read-units: 284,047 [145 GB]
    written-units: 1,258,430 [644 GB]
  ID-1: / raw-size: 919.37 GiB size: 919.37 GiB (100.00%) used: 265.09 GiB (28.8%) fs: btrfs
    block-size: 4096 B dev: /dev/dm-0 maj-min: 254:0
    mapped: luks-7d3d3b17-e19b-4057-8fb6-3bcbc8fada45
  ID-2: /boot/efi raw-size: 300 MiB size: 299.4 MiB (99.80%) used: 752 KiB (0.2%) fs: vfat
    block-size: 512 B dev: /dev/nvme0n1p1 maj-min: 259:1
  ID-3: /home raw-size: 919.37 GiB size: 919.37 GiB (100.00%) used: 265.09 GiB (28.8%)
    fs: btrfs block-size: 4096 B dev: /dev/dm-0 maj-min: 254:0
    mapped: luks-7d3d3b17-e19b-4057-8fb6-3bcbc8fada45
  ID-4: /var/log raw-size: 919.37 GiB size: 919.37 GiB (100.00%) used: 265.09 GiB (28.8%)
    fs: btrfs block-size: 4096 B dev: /dev/dm-0 maj-min: 254:0
    mapped: luks-7d3d3b17-e19b-4057-8fb6-3bcbc8fada45
  ID-5: /var/tmp raw-size: 919.37 GiB size: 919.37 GiB (100.00%) used: 265.09 GiB (28.8%)
    fs: btrfs block-size: 4096 B dev: /dev/dm-0 maj-min: 254:0
    mapped: luks-7d3d3b17-e19b-4057-8fb6-3bcbc8fada45
  Kernel: swappiness: 133 (default 60) cache-pressure: 100 (default)
  ID-1: swap-1 type: zram size: 31.09 GiB used: 0 KiB (0.0%) priority: 100 dev: /dev/zram0
  ID-2: swap-2 type: partition size: 34.19 GiB used: 0 KiB (0.0%) priority: -2 dev: /dev/dm-1
    maj-min: 254:1 mapped: luks-47fbec8a-e654-4427-a68c-8d7057c7e828
  System Temperatures: cpu: 22.0 C mobo: N/A
  Fan Speeds (RPM): N/A
  Processes: 344 Uptime: 2h 52m wakeups: 3 Memory: 31.09 GiB used: 2.53 GiB (8.1%) Init: systemd
  v: 251 default: graphical tool: systemctl Compilers: gcc: 12.2.0 Packages: pm: pacman
  pkgs: 1459 libs: 363 tools: octopi,pamac,paru,yay Shell: Zsh (sudo) v: 5.9 running-in: pty
  pts/1 (SSH) inxi: 3.3.22
Garuda (2.6.9-1):
  System install date:     2022-10-26
  Last full system update: 2022-10-27
  Is partially upgraded:   No
  Relevant software:       NetworkManager
  Windows dual boot:       No/Undetected
  Snapshots:               Snapper
  Failed units:            systemd-networkd-wait-online.service
1 Like

I have no idea if this is applicable and maybe you already came across it, but according to this comment osk-sdl can be put in the GRUB command line, perhaps that makes it available early enough?

That is what happens if I do what I did - and is "to late".

The problem is that the standard Garuda installation with full disk encryption (when you click on "encrypt" in the installer) encrypts also Grub.

You have to enter the LUKS passphrase and Grub comes after decryption.

Therefore I am also not sure if /etc/mkinitcpio.conf is even the right place to start.

I ran into this issue with one of my devices, I ended up using a USB device as key for LUKS instead of a passphrase. I think you could get a on-screen keyboard working but it would most probably be an unreliable hack.

Thats what I fear. But an unreliable hack would at least be better than nothing.
I also think about getting a dongle for that. (The Keyboard supports that.) That would at least make it unnecessary to connect a cable everytime.)

But I would also like to really understand the boot chain much better. ("Never stop learning!" ;))
So that is not just convenient to have. I would also be nice to be able to make that happen. And also: It would be nice to be able to boot the tablet unit without any keyboard at all so that I don't have to carry that much stuff around.

I'd suggest reading the arch wiki extensively

You could use a file as LUKS key and put it in a microsd card if your HW has such port.

Also, you could encrypt just the home partition and that may be easier to setup in this scenario.

I indeed did that. And came to a point where I was stuck and need help. Or at least a pointer where to continue. (Right now I try to find out if here might be a way to modify the early boot stage. But it will have to wait until tomorrow. When I can solve it over the weekend I will write the solution here.)

It's not only about the stuff to carry. The device has a mico-sd reader. But it's "under the hood". You have to remove the bumber and open the back plate to access it.

But FDE with encrypted /boot is the way Garuda installs itself. (I did'nt do it myself :wink:). So it seems obvious to modify it from there.
To encrypt just /home would expose many other stuff like Swap and other configurations.

But I will continue my research over the weekend.

1 Like

Well, I am still stuck.

For me it is still unclear when exactly what part is loaded. (And no: reading the Arch Wiki didn't help much there.)

When I boot the first thing (after POST) it says:

Enter passphrase for hd0,gpt2 (<uuid>):

with a blinking cursor. When I enter the Passphrase (with an USB-Keyboard)

Attempting to decrypt master-key

followed by
slot 0 opened
after some time.

Then the GRUB boot menu appears.

I am still not sure when exactly the initramfs which is generated by sudo mkinitcpio -P is loaded.

Is it before I have to enter the LUKS-Passphrase or after the GRUB Menu? If it is after GRUB menu, which part asks for the passphrase?

If it is an the core image and could be modified with something like "early-grub"?

initramfs seems indeed "to late".

Has anyone an idea how to get a virtual keyboard into grubx64.efi?

I really tried to get along with the Instructions for the "Manual configuration of core image for early boot", but I was not able to find out what to include to memdisk.tar.

The Debian Wiki document (linked at the bottom of the ArchWiki document you shared) mentions the password prompt given at the initramfs stage can be skipped, and only the Grub password prompt would be used (which it sounds like you have working), without changing the threat model in an appreciable way.

The device holding the kernel (and the initramfs image) is unlocked by GRUB, but the root device needs to be unlocked again at initramfs stage, regardless whether it’s the same device or not. This is because GRUB boots with the given vmlinuz and initramfs images, but there is currently no way to securely pass cryptographic material (or Device Mapper information) to the kernel. Hence the Device Mapper table is initially empty at initramfs stage; in other words, all devices are locked, and the root device needs to be unlocked again.

To avoid extra passphrase prompts at initramfs stage, a workaround is to unlock via key files stored into the initramfs image. Since the initramfs image now resides on an encrypted device, this still provides protection for data at rest. After all for LUK1 the volume key can already be found by userspace in the Device Mapper table, so one could argue that including key files to the initramfs image – created with restrictive permissions – doesn’t change the threat model for LUKS1 devices. Please note however that for LUKS2 the volume key is normally offloaded to the kernel keyring (hence no longer readable by userspace), while key files lying on disk are of course readable by userspace.

I'm not sure if that is helpful or not. Here is the article if you want to take a look: Full disk encryption, including /boot: Unlocking LUKS devices from GRUB


Thanks for looking into it.

The suggested setup for avoiding it is the default setup which Garuda sets up if you make an encrypted installation.

My problem is the input device which is used to enter the Password before /boot is decrypted. It seems I can only use an USB-Keyboard (for what you have to connect the keyboard by cable every time).

Therefore I would like to have an on screen keyboard (or bluetooth; but I assume that bluetooth is even harder to make work if there is no direct BIOS support like M$ Surface has.)

And it seems it must be baked in grubx64.efi - and that is where I got suck and have absolutely no idea how to do that.

Have you tried adding osk_kms=i915 to the kernel parameters? I am not sure if it is needed, but it appears to be suggested for the other devices here: List of tested devices and settings · ShapeShifter499/osk-sdl_arch Wiki · GitHub

I tired that, too. The Problem is that the kernel parameters seems to be "to late". Everything I edit in /etc/mkinitcpio.conf seems to work only after the grub menu, where you can select the kernel and where the kernel command line is. (As described before)

But the LUKS-Encryption for /boot and the Grub menu is before that. It looks like it has to get into the core image (where a grub boot decryptor is included). On UEFI devices that should be grubx64.efi.

I just have no idea how to do that.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.