Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disk encryption unlock prompt on boot - no on-screen keyboard #400

Open
afalout opened this issue Feb 16, 2021 · 25 comments
Open

Disk encryption unlock prompt on boot - no on-screen keyboard #400

afalout opened this issue Feb 16, 2021 · 25 comments

Comments

@afalout
Copy link

afalout commented Feb 16, 2021

Hello,

When Linux with disk encryption boots, a prompt to unlock the disk appears early in the boot process. This works fine, if one has the hardware (USB) keyboard handy. But with tablets, this is not to be assumed.

Windows with BitLocker offers a on-screen keyboard to unlock the drive before Windows boots.

On SP4, and I assume all other tablets, and current Surface kernel (5.10.16-surface), there is no such option. On the login screen and later, of course, there is.

I looked, but was unable to find if such functionality already exists. Can you please advise if it does, and if not, could it possibly be a feature of this project.

Environment

  • Hardware model: Surface Pro 4
  • Kernel version: 5.10.16-surface
  • Distribution: Ubuntu Groovie

Thanks,
Andrej

@qzed
Copy link
Member

qzed commented Feb 16, 2021

I don't think there's anything like this yet. As far as I can tell, this would have to be implemented as some kernel module, with the additional problem that we'd need early touchscreen support (at least single-touch, which can luckily be handled in-kernel and doesn't require extensive processing).

So I think it's very much possible to create something like this, but probably quite a bit of work. Not sure how much you'd have to change in-kernel with regards to reacting to touch events and doing all the graphics stuff. There are a couple of more pressing issues right now regarding Surface devices specifically, so don't expect anything like this any time soon (from us at least). Since that's a general tablet problem (or even phone problem, if you consider projects like Purism's Librem), you might be able to convince some other people to work on this though.

@StollD
Copy link
Member

StollD commented Feb 19, 2021

I know I am late to the party, but I just saw this issue, heh.

As far as I can tell, this would have to be implemented as some kernel module, with the additional problem that we'd need early touchscreen support

Actually the unlock prompt is not part of the kernel. Its drawn by Plymouth which also draws the startup screen animation. If you dont have plymouth, systemd will create a text-only prompt and ask you for the password. All of this happens in the initramfs, so it would be possible to add iptsd to it and have a working touch screen during early boot.

Its still not easy, and probably out of scope for this project, but since Plymouth is in userspace it might be a bit easier to do it than if it was in the kernel.

@sphh
Copy link
Contributor

sphh commented Feb 19, 2021

Since there is a touchscreen keyboard available in GRUB, I wonder, if this could be a work around:
https://www.unixsheikh.com/tutorials/real-full-disk-encryption-using-grub-on-debian-linux-for-bios.html (especially points 21. and 22.)?

Basically they add a key file to the root partition which is passed by the kernel to the encrypted partition. Obviously, this key file has to be protected. In the tutorial this is done by encrypting the boot partition, but if it were possible to add a password to the key file and GRUB asking for this password … Well, just an idea and I don't know, if that's possible, but I am sure that people cleverer than me can can comment on it. If that's not, there is always the route to encrypt the boot partition as outlined in the tutorial.

@qzed
Copy link
Member

qzed commented Feb 19, 2021

Actually the unlock prompt is not part of the kernel. Its drawn by Plymouth which also draws the startup screen animation. If you dont have plymouth, systemd will create a text-only prompt and ask you for the password. All of this happens in the initramfs, so it would be possible to add iptsd to it and have a working touch screen during early boot.

Oh neat, so we do have an early userspace. That'd make things easier.

Basically they add a key file to the root partition which is passed by the kernel to the encrypted partition. Obviously, this key file has to be protected. In the tutorial this is done by encrypting the boot partition, but if it were possible to add a password to the key file and GRUB asking for this password … Well, just an idea and I don't know, if that's possible, but I am sure that people cleverer than me can can comment on it. If that's not, there is always the route to encrypt the boot partition as outlined in the tutorial.

Oh right, I did something like this ages ago. You essentially encrypt the boot partition, which stores a key file to the root partition (and potentially other files for other partitions, basically all you want to unlock). That way your key file itself is safe (as long as the boot partition is encrypted) and you don't have to enter a second password (just unlock your boot partition in grub). This should work since the on-screen keyboard is available in grub, I think. Just a bit of work to set up.

I don't think that works (securely) without encrypting boot though (don't think you can lock the key file so that grub unlocks it otherwise).

There's also always the option to use something like a USB stick or SD card for storing the key. You'd have to store that unencrypted though if you want to remove the password prompt, which depending on your scenario may be a no-go. I'm using something like this for my NAS. The benefit is automatic unlock while you still have the option to yank the USB stick and destroy the key (so in my case when I want to decommission a storage volume, I can just destroy the key and switch to a new one instead of having to spend a long time overwriting a bunch of data). The drawback of course is that as soon as someone has access to the USB key, you're compromised.

@afalout
Copy link
Author

afalout commented Feb 20, 2021

Well on my SP4 fully working on-screen touch keyboard appears even before the disk encryption unlock prompt
IMG20210220183125
Is this just a SP BIOS/UEFI keyboard which can be enabled in Advanced Device Security -> On Screen Keyboard or a GRUB one? And more importantly, is there a way to use it on disk unlock screen too?
rEFInd UEFI boot manager apparently also has some sort of touch support since 2016.

@afalout
Copy link
Author

afalout commented Feb 20, 2021

More info and some ideas:

@2ndBillGates
Copy link

can anyone help me, also disk encryption but SB2. thank you
https://github.com/linux-surface/linux-surface/discussions/402

@qzed
Copy link
Member

qzed commented Feb 20, 2021

Well on my SP4 fully working on-screen touch keyboard appears even before the disk encryption unlock prompt
IMG20210220183125
Is this just a SP BIOS/UEFI keyboard which can be enabled in Advanced Device Security -> On Screen Keyboard or a GRUB one? And more importantly, is there a way to use it on disk unlock screen too?

This is from the Surface UEFI. It's only available during the boot process, i.e. before the kernel starts booting. So you can't use it for unlocking an encrypted partition with the kernel. The idea @sphh mentioned and I expanded a bit on above is that you can use it to unlock an encrypted boot partition via grub. Since that has to be done by grub/before you can attempt to load the kernel itself, this is still covered by UEFI so the keyboard is still available.

rEFInd UEFI boot manager apparently also has some sort of touch support since 2016.

Has anyone ever tried if this works well with Surface devices? (Edit: Just tested this and it works nicely on my SB2, you just need to set the enable_touch option.) Again, as long as you're still in the bootloader, the touch driver is provided by UEFI (as is the on-screen keyboard during that stage), so I think this should normally work.

@ghost
Copy link

ghost commented Feb 26, 2021

This is from the Surface UEFI. It's only available during the boot process, i.e. before the kernel starts booting. So you can't use it for unlocking an encrypted partition with the kernel. The idea @sphh mentioned and I expanded a bit on above is that you can use it to unlock an encrypted boot partition via grub. Since that has to be done by grub/before you can attempt to load the kernel itself, this is still covered by UEFI so the keyboard is still available.

On openSUSE this is done by default, /boot partition is a subvolume of root partiton. Leaving only a EFI partition and a single btrfs partiton. You do have the drawback of having to type password twice which can be easily fixed.
IMG_20210226_175322
IMG_20210226_175359

However I don't believe it's safe though. With Surface UEFI virtual keyboard others may sneak peak your password because every key press is lit up with no way of disabling. I would rather reattach type cover just to type luks password.

rEFInd route should be used instead.

BTW what about investigating in TPM unlock? it's the default setup in Windows and TPM chip is built into Surface devices.

@qzed
Copy link
Member

qzed commented Feb 26, 2021

However I don't believe it's safe though. With Surface UEFI virtual keyboard others may sneak peak your password because every key press is lit up with no way of disabling.

That's a fair point.

BTW what about investigating in TPM unlock? it's the default setup in Windows and TPM chip is built into Surface devices.

I have never worked with TPM, so I have no clue. I think (at least on pre-gen7 devices) the TPM should be fairly standard.

@PhilDevProg
Copy link

PhilDevProg commented Jan 28, 2023

Here is the issue in the Plymouth Repository: https://gitlab.freedesktop.org/plymouth/plymouth/-/issues/144

PostmarketOS uses this onscreen keyboard: https://gitlab.com/postmarketOS/osk-sdl
Maybe it could be used here too?

@afalout
Copy link
Author

afalout commented Jan 29, 2023

KDE Neon provides drive unlock on boot using BIOS onscreen keyboard by default for at least a year now. It has a loooooong delay, the prompt is far to small to read on hi-DPI screen of a Surface Pro, but it works. Of course, I installed surface-linux kernel on Neon.
So perhaps this is not an issue for Surface kernel devs to solve, but for distro packagers?

@PhilDevProg
Copy link

If distros would implement an osk it would be great but most of them don't have it implemented so a guide on how to do it yourself in the Surface WiKi would be helpful.

@spfanning
Copy link

spfanning commented Jan 30, 2023

I've had success using the TPM to unlock my encrypted root partition on both a SP4 and SB2 following instructions from here. For any systemd distro the command # systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /path/to/luks-partition should work.

@PhilDevProg
Copy link

I've had success using the TPM to unlock my encrypted root partition on both a SP4 and SB2 following instructions from here. For any systemd distro the command # systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /path/to/luks-partition should work.

Hmm, that didn't work for me on Fedora...

@2ndBillGates
Copy link

2ndBillGates commented Feb 2, 2023

I've had success using the TPM to unlock my encrypted root partition on both a SP4 and SB2 following instructions from here. For any systemd distro the command # systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /path/to/luks-partition should work.

Hmm, that didn't work for me on Fedora...

I guess it's because of Fedora using dracut not mkinitcpio? You need to configure it another way like the ArchWiki said.
I had successfully done it on Arch too, did plan to do it on Fedora but don't have time to finish it.

Please let me know if you made it work. Thank you

@PhilDevProg
Copy link

I followed the Arch Wiki and enabled tpm2-tss for dracut and it says that it's enabled but it still shows the LUKS entry.

@spfanning
Copy link

Looking here it sounds like fedora doesn't use systemd in the initramfs and it suggests using clevis for unlocking the root partition.

@PhilDevProg
Copy link

@spfanning That worked great! Thank you

@PhilDevProg
Copy link

PostmarketOS is currently replacing osk-sdl with unl0kr which is using LVGL and renders directly to the Linux framebuffer so it doesn't depend on GPU acceleration.

@interfect
Copy link

Is there a way to make this work on Neon on a Surface Go? That model doesn't appear to have a UEFI keyboard I can enable, so if I turn on Neon encryption and the kernel doesn't provide anything I don't think I will be able to boot with just the tablet.

@wokawoka
Copy link

wokawoka commented Dec 16, 2023

Is there a way to make this work on Neon on a Surface Go? That model doesn't appear to have a UEFI keyboard I can enable, so if I turn on Neon encryption and the kernel doesn't provide anything I don't think I will be able to boot with just the tablet.

I am experiencing the same issue on a Surface Go 2

@afalout
Copy link
Author

afalout commented Dec 16, 2023

PostmarketOS is currently replacing osk-sdl with unl0kr which is using LVGL and renders directly to the Linux framebuffer so it doesn't depend on GPU acceleration.

unl0kr looks great.

Considering that Surface Linux project is all about enabling Linux on tablets...
and disc encryption is a necessity in year 2023...
and tablet is not a tablet if one needs to carry a keyboard around ...
and over 3 years after I opened this issues ...

Is it maybe time to have this functionality included/enabled in some shape or form?

@qzed ?

Thanks

@FearlessSpiff
Copy link

So, I installed osk-sdl to achieve the same but am stuck because the touchscreen does not work. This is on arch with https://github.com/ShapeShifter499/osk-sdl_arch. I have no idea what modules I need for it to work. And then there is iptsd.service which handles touch input but isn't available in initramfs? Maybe somebody can help me with that?

@systemofapwne
Copy link

systemofapwne commented Feb 25, 2024

I got unl0kr including touch working on my Surface Pro 7 with Arch Linux.

I used this AUR package: https://aur.archlinux.org/packages/unl0kr

There were many pitfals to get it running. First a few things:

  • Unl0kr does not appear to start when using systemd-boot initramfs. For an unknown reason, the run-hook never gets executed. This took me half a day to figure out :/
  • One needs to manually patch the run-hook script, until the bug is fixed upstream: Fixed mangling of stdout & stderr that then was piped as 'unlock password' to cryptsetup, resulting in a failed unlock Grosskopf/arch_unl0kr#3
  • To get touch working on the SP7, load the following kernel modules into your initramfs: ipts mei mei_me
  • Your kernel cmdline must state the cryptdevice like cryptdevice=UUID=4fe2c1d8-fd13-489b-be73-7fe7ad18afc5:cryptroot. Be aware, that appending additional cryptsetup options like cryptdevice=UUID=4fe2c1d8-fd13-489b-be73-7fe7ad18afc5:cryptroot:allow-discards,no-read-workqueue,no-write-workqueue confuses the unl0kr script.

Here is a strapped down /etc/mkinitcpio.conf, that I am using on my system:

# Load modules for touch support
MODULES=(ipts mei mei_me)

# Systemd boot + unl0kr (DOES NOT LOAD unl0kr hook!)
#HOOKS=(systemd autodetect modconf block keyboard sd-vconsole unl0kr sd-encrypt lvm2 filesystems)

# Normal boot + unl0kr
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block unl0kr encrypt lvm2 filesystems)

COMPRESSION="zstd"

Workaround/Fixes

As already stated, there is currently a bug in the unl0kr AUR (Grosskopf/arch_unl0kr#3), that prevented me from unlocking the disk. The fix is easy:
After installing unl0kr, edit /usr/lib/initcpio/hooks/unl0kr and change the line 38 from

unl0kr | cryptsetup open "${cryptdev}" "${cryptname}"

to

unl0kr 2> /dev/null | cryptsetup open "${cryptdev}" "${cryptname}"

Tweak boottime

The unl0kr AUR includes various dri drivers in the initramfs, blowing it artificially up: Grosskopf/arch_unl0kr#4

This increases the size of the initramfs in my case from 40 MB -> 200 MB. Since I use SecureBoot with custom keys and EFIStub kernel, every bootable part is cryptographically checked against these keys and "size matters". This prolonged my boot by > 10s.

By editing /usr/lib/initcpio/install/unl0kr and commenting out line 31 to 36 to look like this, I had a slim and fast booting initramfs again!

    #DRI_drivers="vmgfx_dri.so virtio_gpu_dri.so i965_drv_video.so crocus_dri.so iris_dri.so nouveau_dri.so r300_dri.so r600_dri.so radeonsi_dri.so zink_dri.so kms_swrast_dri.so"
    #for so in $DRI_drivers; do
    #  if [ -f "$libdir/dri/$so" ]; then
    #      add_binary "$libdir/dri/$so"
    #  fi
    #done

Note, that these drivers are added in order to support hardware acceleration across many different platforms, by installing drivers for multiple platforms. Howeer, I have not seen any benefi of them being there. Just downsides (loadtime). In fact, without theses drivers added to initramfs, everything worked perfectly for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests