{"id":13602301,"url":"https://github.com/agherzan/yubikey-full-disk-encryption","last_synced_at":"2025-05-16T14:06:43.468Z","repository":{"id":17463429,"uuid":"82033521","full_name":"agherzan/yubikey-full-disk-encryption","owner":"agherzan","description":"Use YubiKey to unlock a LUKS partition","archived":false,"fork":false,"pushed_at":"2024-05-06T23:35:38.000Z","size":156,"stargazers_count":841,"open_issues_count":21,"forks_count":51,"subscribers_count":33,"default_branch":"master","last_synced_at":"2025-04-19T15:56:28.853Z","etag":null,"topics":["archlinux","disk-encryption","encryption","initramfs","linux","luks","luks-partition","unlock","yubico","yubikey"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agherzan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-15T07:41:08.000Z","updated_at":"2025-04-18T11:10:30.000Z","dependencies_parsed_at":"2024-05-07T00:29:30.262Z","dependency_job_id":"cdf32517-6603-4d5c-8b3c-fb5b10dab829","html_url":"https://github.com/agherzan/yubikey-full-disk-encryption","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agherzan%2Fyubikey-full-disk-encryption","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agherzan%2Fyubikey-full-disk-encryption/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agherzan%2Fyubikey-full-disk-encryption/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agherzan%2Fyubikey-full-disk-encryption/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agherzan","download_url":"https://codeload.github.com/agherzan/yubikey-full-disk-encryption/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["archlinux","disk-encryption","encryption","initramfs","linux","luks","luks-partition","unlock","yubico","yubikey"],"created_at":"2024-08-01T18:01:19.667Z","updated_at":"2025-05-16T14:06:43.407Z","avatar_url":"https://github.com/agherzan.png","language":"Shell","funding_links":[],"categories":["Shell","Not tested","archlinux"],"sub_categories":[],"readme":"# YubiKey Full Disk Encryption\n\nThis project leverages a [YubiKey](https://wiki.archlinux.org/index.php/Yubikey) [HMAC-SHA1 Challenge-Response](https://wiki.archlinux.org/index.php/Yubikey#Challenge-Response) mode for creating strong [LUKS](https://gitlab.com/cryptsetup/cryptsetup) encrypted volume passphrases. It can be used in intramfs stage during boot process as well as on running system.\n\nBe aware that this was only tested and intended for:\n\n* [Arch Linux](https://www.archlinux.org/) and its derivatives\n* [YubiKey (version 4 or later)](https://www.yubico.com/products/yubikey-5-overview/)\n\nThere is similar project targeting [Debian](https://www.debian.org/)/[Ubuntu](https://www.ubuntu.com/) based systems: [yubikey-luks](https://github.com/cornelinux/yubikey-luks)\n\nTable of Contents\n=================\n\n   * [YubiKey Full Disk Encryption](#yubikey-full-disk-encryption)\n   * [Table of Contents](#table-of-contents)\n   * [Design](#design)\n      * [Automatic mode with stored challenge (1FA)](#automatic-mode-with-stored-challenge-1fa)\n      * [Manual mode with secret challenge (2FA)](#manual-mode-with-secret-challenge-2fa)\n   * [Install](#install)\n      * [From Arch Linux official repository](#from-arch-linux-official-repository)\n      * [From Github using 'makepkg'](#from-github-using-makepkg)\n      * [From Github using 'make'](#from-github-using-make)\n   * [Configure](#configure)\n      * [Configure HMAC-SHA1 Challenge-Response slot in YubiKey](#configure-hmac-sha1-challenge-response-slot-in-yubikey)\n      * [Edit /etc/ykfde.conf file](#edit-etcykfdeconf-file)\n   * [Usage](#usage)\n      * [Format new LUKS encrypted volume using ykfde passphrase](#format-new-luks-encrypted-volume-using-ykfde-passphrase)\n      * [Enroll ykfde passphrase to existing LUKS encrypted volume](#enroll-ykfde-passphrase-to-existing-luks-encrypted-volume)\n      * [Enroll new ykfde passphrase to existing LUKS encrypted volume protected by old ykfde passphrase](#enroll-new-ykfde-passphrase-to-existing-luks-encrypted-volume-protected-by-old-ykfde-passphrase)\n      * [Unlock LUKS encrypted volume protected by ykfde passphrase](#unlock-luks-encrypted-volume-protected-by-ykfde-passphrase)\n      * [Kill ykfde passphrase for existing LUKS encrypted volume](#kill-ykfde-passphrase-for-existing-luks-encrypted-volume)\n      * [Enable ykfde initramfs hook](#enable-ykfde-initramfs-hook)\n      * [Enable NFC support in ykfde initramfs hook (experimental)](#enable-nfc-support-in-ykfde-initramfs-hook-experimental)\n      * [Enable ykfde suspend service (experimental)](#enable-ykfde-suspend-service-experimental)\n   * [License](#license)\n\n# Design\n\nThe passphrase for unlocking *LUKS* encrypted volumes can be created in two ways:\n\n## Automatic mode with stored challenge (1FA)\n\nIn *Automatic mode* you create custom *challenge* with 0-64 byte length and store it in cleartext in */etc/ykfde.conf* and inside the initramfs image.\n\nExample *challenge*:`123456abcdef`\n\nThe *YubiKey* *response* is a *HMAC-SHA1* 40 byte length string created from your provided challenge and 20 byte length secret key stored inside the token. It will be used as your *LUKS* encrypted volume passphrase.\n\nExample *response* (ykfde passphrase): `bd438575f4e8df965c80363f8aa6fe1debbe9ea9`\n\nIn this mode possession of your *YubiKey* is enough to unlock a *LUKS* encrypted volume (1FA). It allows for the easy unlocking of encrypted volumes when *YubiKey* is present without need for user action.\n\n\n## Manual mode with secret challenge (2FA)\n\nIn *Secret mode* you will be asked to provide a custom *challenge* every time you want to unlock your *LUKS* encrypted volume as it will never be stored anywhere on system.\n\nExample *challenge*: `123456abcdef`\n\nIt will be hashed using the *SHA256* algorithm to achieve constant byte length (64) for any given *challenge*. It's also the maximum length that *YubiKey* can take as input. The hash will be used as the final *challenge* provided for *YubiKey*.\n\nHashing function:\n\n```\nprintf 123456abcdef | sha256sum | awk '{print $1}'\n```\n\nExample hashed *challenge*: `8fa0acf6233b92d2d48a30a315cd213748d48f28eaa63d7590509392316b3016`\n\n The *YubiKey* *response* is a *HMAC-SHA1* 40 byte length string created from your provided *challenge* and 20 byte length secret key stored inside the token. It will be concatenated with the *challenge* and used as your *LUKS* encrypted volume passphrase for a total length of 104 (64+40) bytes.\n\nExample response: `bd438575f4e8df965c80363f8aa6fe1debbe9ea9`\n\nExample ykfde passphrase: `8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92bd438575f4e8df965c80363f8aa6fe1debbe9ea9`\n\nThis strong passphrase cannot be broken by brute force. To recreate it one would need both your passphrase (something you know) and your *YubiKey* (something you have) which means it works like 2FA.\n\nKeep in mind that the above doesn't protect you from physical tampering like *evil maid attack* and from *malware* running after you unlock and boot your system. Use security tools designed to prevent those attacks.\n\n# Install\n\n## From Arch Linux official repository\n\nThe easiest way is to install package from [official Arch Linux repository](https://www.archlinux.org/packages/community/any/yubikey-full-disk-encryption/).\n\n```\nsudo pacman -Syu yubikey-full-disk-encryption\n```\n\n## From Github using 'makepkg'\n\n```\nwget https://raw.githubusercontent.com/agherzan/yubikey-full-disk-encryption/master/PKGBUILD\nmakepkg -srci\n```\n\n## From Github using 'make'\n\n```\ngit clone https://github.com/agherzan/yubikey-full-disk-encryption.git\ncd yubikey-full-disk-encryption\nsudo make install\n```\n\nWhen installing by using `make` you also need to install [yubikey-personalization](https://www.archlinux.org/packages/community/x86_64/yubikey-personalization/) and [expect](https://www.archlinux.org/packages/extra/x86_64/expect/) packages.\n\n# Configure\n\n\n## Configure HMAC-SHA1 Challenge-Response slot in YubiKey\n\nFirst of all you need to [setup a configuration slot](https://wiki.archlinux.org/index.php/Yubikey#Setup_the_slot) for *YubiKey HMAC-SHA1 Challenge-Response* mode using a command similar to:\n\n```\nykpersonalize -v -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible -ochal-btn-trig\n```\n\nAbove arguments mean:\n\n* Verbose output (`-v`)\n* Use slot 2 (`-2`)\n* Set Challenge-Response mode (`-ochal-resp`)\n* Generate HMAC-SHA1 challenge responses (`-ochal-hmac`)\n* Calculate HMAC on less than 64 bytes input (`-ohmac-lt64`)\n* Allow YubiKey serial number to be read using an API call (`-oserial-api-visible`)\n* Require touching YubiKey before issue response (`-ochal-btn-trig`) *(optional)*\n\nThis command will enable *HMAC-SHA1 Challenge-Response* mode on a chosen slot and write random 20 byte length secret key to your YubiKey which will be used for creating ykfde passphrases.\n\n**Warning: choosing YubiKey slot already configured for *HMAC-SHA1 Challenge-Response* mode will overwrite secret key with the new one which means ykfde passphrases created with the old key will be unrecoverable.**\n\nYou may instead enable *HMAC-SHA1 Challenge-Response* mode using graphical interface through [yubikey-personalization-gui](https://www.archlinux.org/packages/community/x86_64/yubikey-personalization-gui/) package. It allows for customization of the secret key, creation of secret key backup and writing the same secret key to multiple YubiKeys which allows for using them interchangeably for creating same ykfde passphrases.\n\n## Edit /etc/ykfde.conf file\n\nOpen the [/etc/ykfde.conf](https://github.com/agherzan/yubikey-full-disk-encryption/blob/master/src/ykfde.conf) file and adjust it for your needs. Alternatively to setting `YKFDE_DISK_UUID` and `YKFDE_LUKS_NAME`, you can use `cryptdevice` kernel parameter. The [syntax](https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Configuring_the_kernel_parameters) is compatible with Arch's `encrypt` hook. After making your changes [regenerate initramfs](https://wiki.archlinux.org/index.php/Mkinitcpio#Image_creation_and_activation):\n\n```\nsudo mkinitcpio -P\n```\n\n\n# Usage\nYou can list existing LUKS key slots with `cryptsetup luksDump /dev/\u003cdevice\u003e`.\n\n## Format new LUKS encrypted volume using ykfde passphrase\n\nTo format new *LUKS* encrypted volume, you can use [ykfde-format](https://github.com/agherzan/yubikey-full-disk-encryption/blob/master/src/ykfde-format) script which is wrapper over `cryptsetup luksFormat` command:\n\n```\nykfde-format --cipher aes-xts-plain64 --key-size 512 --hash sha512 /dev/\u003cdevice\u003e\n```\n\n## Enroll ykfde passphrase to existing LUKS encrypted volume\n\nTo enroll new ykfde passphrase to existing *LUKS* encrypted volume you can use [ykfde-enroll](https://github.com/agherzan/yubikey-full-disk-encryption/blob/master/src/ykfde-enroll) script, see `ykfde-enroll -h` for help:\n\n```\nykfde-enroll -d /dev/\u003cdevice\u003e -s \u003ckeyslot_number\u003e\n```\n\n**Warning: having a weaker non-ykfde passphrase(s) on the same *LUKS* encrypted volume undermines the ykfde passphrase value as potential attacker will always try to break the weaker passphrase. Make sure the other  non-ykfde passphrases are similarly strong or remove them.**\n\n## Enroll new ykfde passphrase to existing LUKS encrypted volume protected by old ykfde passphrase\n\nTo enroll new ykfde passphrase to existing *LUKS* encrypted volume protected by old ykfde passphrase you can use [ykfde-enroll](https://github.com/agherzan/yubikey-full-disk-encryption/blob/master/src/ykfde-enroll) script, see `ykfde-enroll -h` for help:\n\n```\nykfde-enroll -d /dev/\u003cdevice\u003e -s \u003ckeyslot_number\u003e -o\n```\n\n## Unlock LUKS encrypted volume protected by ykfde passphrase\n\nTo unlock *LUKS* encrypted volume on a running system, you can use [ykfde-open](https://github.com/agherzan/yubikey-full-disk-encryption/blob/master/src/ykfde-open) script, see `ykfde-open -h` for help.\n\nAs unprivileged user using udisksctl (recommended):\n\n```\nykfde-open -d /dev/\u003cdevice\u003e\n```\n\nAs root using cryptsetup (when [udisks2](https://www.archlinux.org/packages/extra/x86_64/udisks2/) or [expect](https://www.archlinux.org/packages/extra/x86_64/expect/) aren't available):\n\n```\nykfde-open -d /dev/\u003cdevice\u003e -n \u003cvolume_name\u003e\n```\n\nTo print only the ykfde passphrase to the console without unlocking any volumes:\n\n```\nykfde-open -p\n```\n\nTo test only a passphrase for a specific key slot:\n\n```\nykfde-open -d /dev/\u003cdevice\u003e -s \u003ckeyslot_number\u003e -t\n```\n\nTo use optional parameters, example, use an external luks header:\n\n```\nykfde-open -d /dev/\u003cdevice\u003e -- --header /mnt/luks-header.img\n```\n\n## Kill ykfde passphrase for existing LUKS encrypted volume\n\nTo kill a ykfde passphrase for existing *LUKS* encrypted volume you can use [ykfde-enroll](https://github.com/agherzan/yubikey-full-disk-encryption/blob/master/src/ykfde-enroll) script, see `ykfde-enroll -h` for help:\n\n```\nykfde-enroll -d /dev/\u003cdevice\u003e -s \u003ckeyslot_number\u003e -k\n```\n\n## Enable ykfde initramfs hook\n\n**Warning: It's recommended to have already working [encrypted system setup](https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system) with `encrypt` hook and non-ykfde passphrase before starting to use `ykfde` hook with ykfde passphrase to avoid potential misconfigurations.**\n\nEdit `/etc/mkinitcpio.conf` and add the `ykfde` hook before or instead of `encrypt` hook as provided in [example](https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration#Examples). Adding `ykfde` hook before `encrypt` hook will allow for a safe fallback in case of ykfde misconfiguration. You can remove `encrypt` hook later when you confim that everything is working correctly. After making your changes [regenerate initramfs](https://wiki.archlinux.org/index.php/Mkinitcpio#Image_creation_and_activation):\n\n```\nsudo mkinitcpio -P\n```\n\nReboot and test your configuration.\n\n## Enable NFC support in ykfde initramfs hook (experimental)\n\n**Warning: Currently NFC support is implemented only in initramfs hook. All ykfde manipulations on booted system have to be done through USB.**\n\nNFC support is provided through [libnfc](https://www.archlinux.org/packages/community/x86_64/libnfc/) and [ykchalresp-nfc](https://aur.archlinux.org/packages/ykchalresp-nfc/) tools. Make sure you have both packages installed. Edit `/etc/ykfde.conf` and uncomment `YKFDE_NFC=\"1\"`setting. After making your changes [regenerate initramfs](https://wiki.archlinux.org/index.php/Mkinitcpio#Image_creation_and_activation):\n\n```\nsudo mkinitcpio -P\n```\n\nReboot and test your configuration.\n\n## Enable ykfde suspend service (experimental)\n\nYou can enable the `ykfde-suspend` service which allows for automatically locking encrypted *LUKS* volumes and wiping keys from memory on suspend and unlocking them on resume by using `cryptsetup luksSuspend` and `cryptsetup luksResume` commands.\n\n**Warning: RAM storage stays unencrypted in that case.**\n\nEdit `/etc/mkinitcpio.conf` and add `shutdown` hook as the last in `HOOKS` array. After making your changes [regenerate initramfs](https://wiki.archlinux.org/index.php/Mkinitcpio#Image_creation_and_activation):\n\n```\nsudo mkinitcpio -P\n```\n\nEnable related systemd service:\n\n```\nsystemctl enable ykfde-suspend.service\n```\n\nReboot and test your configuration.\n\n# License\n\nCopyright 2017 Andrei Gherzan\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagherzan%2Fyubikey-full-disk-encryption","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagherzan%2Fyubikey-full-disk-encryption","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagherzan%2Fyubikey-full-disk-encryption/lists"}