Skip to content

Instantly share code, notes, and snippets.

@DragoonAethis
Last active May 21, 2020 15:17
Show Gist options
  • Save DragoonAethis/ff776d5c27e225970f2ff0f92f400a61 to your computer and use it in GitHub Desktop.
Save DragoonAethis/ff776d5c27e225970f2ff0f92f400a61 to your computer and use it in GitHub Desktop.
mikintcpio-scboot: unlock a LUKS volume using a key stored on a smart card

mkinitcpio-scboot

Inspect the PKGBUILD for dependencies and where to place the install/hooks scripts. After that's done, add the scboot hook to your mkinitcpio.conf BEFORE the encrypt hook. (sd-encrypt is not supported.) Then regenerate your image with # mkinitcpio -P.

The smart card should contain a data object with the luks label which is a key file to open the LUKS root volume. You can generate a new key file like this: dd if=/dev/urandom of=key.bin bs=1 count=256, then cryptsetup luksAddKey /dev/sda1 key.bin to add it to the volume.

The key can be placed on your card using the manufacturer's software or: pkcs11-tool --login --write-object key.bin --type data --label luks.

(CardOS 5.3 cards require the official software for provisioning.)

pkgname=mkinitcpio-scboot
pkgver=1.0.0
pkgrel=1
pkgdesc="Boot from an encrypted partition using a key stored on a smart card."
author=('Dragoon Aethis <dragoon@dragonic.eu>')
license=('MIT')
arch=('any')
source=('scboot-hooks.sh' 'scboot-install')
sha256sums=('SKIP' 'SKIP')
depends=('opensc' 'libusb' 'libusb-compat' 'pcsclite' 'ccid' 'acsccid' 'mkinitcpio')
package() {
install -Dm644 "${srcdir}/scboot-hooks.sh" "${pkgdir}/usr/lib/initcpio/hooks/scboot"
install -Dm644 "${srcdir}/scboot-install.sh" "${pkgdir}/usr/lib/initcpio/install/scboot"
}
#!/usr/bin/ash
run_hook() {
# PCSC must go up first as it runs the card readers.
pcscd
echo "Waiting for pcscd to settle..."
sleep 3
echo "Probing readers..."
opensc-tool --list-readers
# Check if there's any reader available, and if not...
opensc-tool --list-readers | grep "No smart card readers found."
if [ $? -eq 0 ]; then
echo "No card reader available, skipping smart card boot."
return 0
fi
# Probe for the card
opensc-tool --name --wait
if [ $? -ne 0 ]; then
echo "No card available, skipping smart card boot."
return 0
fi
pkcs11-tool --login --read-object --label luks --type data --output-file /crypto_keyfile.bin
if [ $? -ne 0 ]; then
echo "Cannot read the key file, skipping smart card boot."
return 0
fi
echo "Key file read, will be used in the encrypt hook in a moment..."
return 0
}
#!/bin/bash
build() {
local mod
# OpenSC tools and libs
add_binary "pkcs11-tool"
add_binary "opensc-tool"
add_binary "opensc-asn1"
add_binary "opensc-explorer"
add_file "/etc/opensc.conf"
add_file "/usr/lib/libsmm-local.so"
add_file "/usr/lib/libsmm-local.so.6"
add_file "/usr/lib/libsmm-local.so.6.0.0"
add_file "/usr/lib/opensc-pkcs11.so"
add_file "/usr/lib/onepin-opensc-pkcs11.so"
add_file "/usr/lib/pkcs11-spy.so"
add_file "/usr/lib/pkcs11/onepin-opensc-pkcs11.so"
add_file "/usr/lib/pkcs11/opensc-pkcs11.so"
add_file "/usr/lib/pkcs11/pkcs11-spy.so"
add_file "/usr/share/opensc/asepcos.profile"
add_file "/usr/share/opensc/authentic.profile"
add_file "/usr/share/opensc/cardos.profile"
add_file "/usr/share/opensc/cyberflex.profile"
add_file "/usr/share/opensc/entersafe.profile"
add_file "/usr/share/opensc/epass2003.profile"
add_file "/usr/share/opensc/flex.profile"
add_file "/usr/share/opensc/gids.profile"
add_file "/usr/share/opensc/gpk.profile"
add_file "/usr/share/opensc/ias_adele_admin1.profile"
add_file "/usr/share/opensc/ias_adele_admin2.profile"
add_file "/usr/share/opensc/ias_adele_common.profile"
add_file "/usr/share/opensc/iasecc.profile"
add_file "/usr/share/opensc/iasecc_admin_eid.profile"
add_file "/usr/share/opensc/iasecc_generic_oberthur.profile"
add_file "/usr/share/opensc/iasecc_generic_pki.profile"
add_file "/usr/share/opensc/incrypto34.profile"
add_file "/usr/share/opensc/isoApplet.profile"
add_file "/usr/share/opensc/jcop.profile"
add_file "/usr/share/opensc/miocos.profile"
add_file "/usr/share/opensc/muscle.profile"
add_file "/usr/share/opensc/myeid.profile"
add_file "/usr/share/opensc/oberthur.profile"
add_file "/usr/share/opensc/openpgp.profile"
add_file "/usr/share/opensc/pkcs15.profile"
add_file "/usr/share/opensc/rutoken.profile"
add_file "/usr/share/opensc/rutoken_ecp.profile"
add_file "/usr/share/opensc/rutoken_lite.profile"
add_file "/usr/share/opensc/sc-hsm.profile"
add_file "/usr/share/opensc/setcos.profile"
add_file "/usr/share/opensc/starcos.profile"
add_file "/usr/share/opensc/westcos.profile"
# PCSC card reader daemon
add_binary "pcscd"
add_file "/usr/lib/libpcsclite.so"
add_file "/usr/lib/libpcsclite.so.1"
add_file "/usr/lib/libpcsclite.so.1.0.0"
add_file "/usr/lib/libpcscspy.so"
add_file "/usr/lib/libpcscspy.so.0"
add_file "/usr/lib/libpcscspy.so.0.0.0"
add_file "/usr/lib/libusb-1.0.so"
add_file "/usr/lib/libusb-1.0.so.0"
add_file "/usr/lib/libusb-1.0.so.0.2.0"
# Needed to handle common card readers
add_file "/usr/lib/pcsc/drivers/serial/libccidtwin.so"
add_file "/usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist"
add_file "/usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Linux/libccid.so"
# ...and ACS card readers.
add_file "/usr/lib/pcsc/drivers/ifd-acsccid.bundle/Contents/Info.plist"
add_file "/usr/lib/pcsc/drivers/ifd-acsccid.bundle/Contents/Linux/libacsccid.so"
# libusb-compat (for ACS)
add_binary "libusb-config"
add_file "/usr/lib/libusb.so"
add_file "/usr/lib/libusb-0.1.so.4"
add_file "/usr/lib/libusb-0.1.so.4.4.4"
add_runscript
}
help() {
cat <<HELPEOF
This hook allows unlocking an encrypted root device using a LUKS key stored on
a smart card. OpenSC and related tools are added to the initrd so that they're
available for card manipulation during early boot.
The way this works is that we run pcscd and wait for reader availability before
the encrypt hook. If a reader is not detected, the hook continues regular boot.
With a reader, the user is prompted to insert a card. If a card is still not
available, continue regular boot. Then prompt to log into the card.
A data object called "luks" is fetched via the pkcs11-tool. If the object does
not exist or the user couldn't authenticate, we also continue regular boot.
The key file is placed in the location expected by the encrypt hook to be used
a moment later in the boot process.
HELPEOF
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment