Masking LUKS/Console passphrase input with asterisks


2022-11-07

The situation


My main laptop boots using my self-made minimal initramfs image which launches cryptsetup before mounting partitions and executing init. My password is over 50 characters long. No, it's not very convenient typing it in every day... but I prefer it over the alternatives.

What makes long passphrases especially annoying though is typing them in incorrectly. Then you have to start again. cryptsetup receives passwords in "no echo" mode as is standard on Unix/Linux. So, what if you hit the wrong key at char 42? You wouldn't know probably until you enter it fully and cryptsetup tells you that it's wrong.

What if some keys on an older laptop of yours begin to react poorly? You will not notice such case in the "no echo" mode either. (Yeah, that happened to me).

So an alternative might look like:

read PASSWORD
echo -n "$PASSWORD" | cryptsetup luksOpen
unset PASSWORD

This way you can see your password, check whether you typed it in correctly and correct it if necessary. There are a few things that are wrong here though, the most obvious one is that your password is visible for everyone who can see your screen. You may not have such problem at home, but it is an issue in public places. The password may also end up in core dumps or swap space and be susceptible to cold boot attacks (though LUKS itself is without patches such as TRESOR).

This means we need something else, something that may mask the input. cryptsetup has no mode to show asterisks (*) when entering the passphrase though. What to do?

Surprisingly, I did not find anything suitable for my case: A simple console tool to show asterisks when typing in passwords. systemd-ask-password offers such functionality. However, even if we assume it would be possible to run it without systemd, it's unsuitable for my small initramfs environment. A quick "ldd" simply shows too many dependencies.

I have also seen plymouth and other "boot splash" solutions showing asterisks in their cryptsetup frontend. However, my initrd does not use them and are not an option for me personally.

The solution


So I quickly hacked my own tool: asteriskify (yeah yeah, I am really amazing at naming things...). It reads the password from stdin and writes it to stdout. The idea is you pipe it to programs expecting passwords over stdin, such as cryptsetup. asteriskify either simply echoes the password, or you switch to asterisk mode by pressing TAB. You can also always reveal the last character with Ctrl + R. Maybe it could be useful to some souls out there.

As a side note: I have seen some people seriously claim the "no echo" mode is a security feature, as with asterisks an attacker can see how long your password is. This is supposed to be an issue. I disagree. For a reasonably long password, knowing only the length does not help an attacker much in practical aspects. I suspect one of the main reasons that "echo off" is the default might be that it's simply easier to implement.

For comments/remarks: Contact me

Disclaimer: Opinions are my own. If you act on the information presented in this post, you are doing so at your own risk.