From 9e8781328e497dc3725371d731b1a7aa0fc9f90f Mon Sep 17 00:00:00 2001 From: Ctem Date: Mon, 21 Dec 2020 06:24:14 +0900 Subject: [PATCH 1/2] boot.initrd.luks: add reusePassphrases support for YubiKey 2FA --- nixos/modules/system/boot/luksroot.nix | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 8dd2ea20519..7b9101fb772 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -254,8 +254,27 @@ let for try in $(seq 3); do ${optionalString yubikey.twoFactor '' echo -n "Enter two-factor passphrase: " - read -r k_user - echo + k_user= + while true; do + if [ -e /crypt-ramfs/passphrase ]; then + echo "reused" + k_user=$(cat /crypt-ramfs/passphrase) + break + else + # Try reading it from /dev/console with a timeout + IFS= read -t 1 -r k_user + if [ -n "$k_user" ]; then + ${if luks.reusePassphrases then '' + # Remember it for the next device + echo -n "$k_user" > /crypt-ramfs/passphrase + '' else '' + # Don't save it to ramfs. We are very paranoid + ''} + echo + break + fi + fi + done ''} if [ ! -z "$k_user" ]; then @@ -268,6 +287,11 @@ let if [ $? == 0 ]; then opened=true + ${if luks.reusePassphrases then '' + # We don't rm here because we might reuse it for the next device + '' else '' + rm -f /crypt-ramfs/passphrase + ''} break else opened=false From 1c9b2f18ced655b19bf01ad7d5ef9497d48a32cf Mon Sep 17 00:00:00 2001 From: Ctem Date: Mon, 21 Dec 2020 06:35:59 +0900 Subject: [PATCH 2/2] boot.initrd.luks: fix case `Yubikey` -> `YubiKey` --- nixos/modules/system/boot/luksroot.nix | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 7b9101fb772..fa14d86e253 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -56,7 +56,7 @@ let ykinfo -v 1>/dev/null 2>&1 if [ $? != 0 ]; then - echo -n "Waiting $secs seconds for Yubikey to appear..." + echo -n "Waiting $secs seconds for YubiKey to appear..." local success=false for try in $(seq $secs); do echo -n . @@ -118,7 +118,7 @@ let # Cryptsetup locking directory mkdir -p /run/cryptsetup - # For Yubikey salt storage + # For YubiKey salt storage mkdir -p /crypt-storage ${optionalString luks.gpgSupport '' @@ -218,7 +218,7 @@ let } ${optionalString (luks.yubikeySupport && (yubikey != null)) '' - # Yubikey + # YubiKey rbtohex() { ( od -An -vtx1 | tr -d ' \n' ) } @@ -244,7 +244,7 @@ let local new_k_luks mount -t ${yubikey.storage.fsType} ${yubikey.storage.device} /crypt-storage || \ - die "Failed to mount Yubikey salt storage device" + die "Failed to mount YubiKey salt storage device" salt="$(cat /crypt-storage${yubikey.storage.path} | sed -n 1p | tr -d '\n')" iterations="$(cat /crypt-storage${yubikey.storage.path} | sed -n 2p | tr -d '\n')" @@ -341,7 +341,7 @@ let if wait_yubikey ${toString yubikey.gracePeriod}; then do_open_yubikey else - echo "No yubikey found, falling back to non-yubikey open procedure" + echo "No YubiKey found, falling back to non-YubiKey open procedure" open_normally fi } @@ -689,8 +689,8 @@ in yubikey = mkOption { default = null; description = '' - The options to use for this LUKS device in Yubikey-PBA. - If null (the default), Yubikey-PBA will be disabled for this device. + The options to use for this LUKS device in YubiKey-PBA. + If null (the default), YubiKey-PBA will be disabled for this device. ''; type = with types; nullOr (submodule { @@ -698,13 +698,13 @@ in twoFactor = mkOption { default = true; type = types.bool; - description = "Whether to use a passphrase and a Yubikey (true), or only a Yubikey (false)."; + description = "Whether to use a passphrase and a YubiKey (true), or only a YubiKey (false)."; }; slot = mkOption { default = 2; type = types.int; - description = "Which slot on the Yubikey to challenge."; + description = "Which slot on the YubiKey to challenge."; }; saltLength = mkOption { @@ -728,7 +728,7 @@ in gracePeriod = mkOption { default = 10; type = types.int; - description = "Time in seconds to wait for the Yubikey."; + description = "Time in seconds to wait for the YubiKey."; }; /* TODO: Add to the documentation of the current module: @@ -803,9 +803,9 @@ in default = false; type = types.bool; description = '' - Enables support for authenticating with a Yubikey on LUKS devices. + Enables support for authenticating with a YubiKey on LUKS devices. See the NixOS wiki for information on how to properly setup a LUKS device - and a Yubikey to work with this feature. + and a YubiKey to work with this feature. ''; }; @@ -823,7 +823,7 @@ in assertions = [ { assertion = !(luks.gpgSupport && luks.yubikeySupport); - message = "Yubikey and GPG Card may not be used at the same time."; + message = "YubiKey and GPG Card may not be used at the same time."; } { assertion = !(luks.gpgSupport && luks.fido2Support); @@ -831,7 +831,7 @@ in } { assertion = !(luks.fido2Support && luks.yubikeySupport); - message = "FIDO2 and Yubikey may not be used at the same time."; + message = "FIDO2 and YubiKey may not be used at the same time."; } ];