From 4114606c72147a3c2918bdca1a9cf5ef164bc06d Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 6 Sep 2016 02:23:03 -0500 Subject: [PATCH] Gracefully handle lack of random data in early system startup Speed up PC/SC launch --- src/cardpincheck.c | 12 +++++++---- usr/bin/cryptosmartcard.sh | 41 ++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/cardpincheck.c b/src/cardpincheck.c index e6c1cc4..f1e730f 100644 --- a/src/cardpincheck.c +++ b/src/cardpincheck.c @@ -192,13 +192,13 @@ int main(int argc, char* argv[]) { file_to_decrypt = argv[2]; } - fprintf(stderr, "Initializing pkcs11-helper\n"); + fprintf(stderr, "Initializing pkcs11-helper\n"); fflush(stderr); if ((rv = pkcs11h_initialize()) != CKR_OK) { fprintf(stderr, "pkcs11h_initialize failed: %s\n", pkcs11h_getMessage(rv)); return -1; } - fprintf(stderr, "Registering pkcs11-helper hooks\n"); + fprintf(stderr, "Registering pkcs11-helper hooks\n"); fflush(stderr); if ((rv = pkcs11h_setLogHook(pkcs_log_hook, NULL)) != CKR_OK) { fprintf(stderr, "pkcs11h_setLogHook failed: %s\n", pkcs11h_getMessage(rv)); return -1; @@ -223,7 +223,7 @@ int main(int argc, char* argv[]) { return -1; } - fprintf(stderr, "Adding provider '%s'\n", opensc_provider_library); + fprintf(stderr, "Adding provider '%s'\n", opensc_provider_library); fflush(stderr); if ((rv = pkcs11h_addProvider(opensc_provider_library, opensc_provider_library, FALSE, PKCS11H_PRIVATEMODE_MASK_AUTO, PKCS11H_SLOTEVENT_METHOD_AUTO, 0, FALSE)) != CKR_OK) { fprintf(stderr, "pkcs11h_addProvider failed: %s\n", pkcs11h_getMessage(rv)); return -1; @@ -284,7 +284,11 @@ int main(int argc, char* argv[]) { // Check PIN rv = pkcs11h_certificate_ensureKeyAccess(certificate); if (rv != CKR_OK) { - if (rv == CKR_CANCEL) { + if (rv == CKR_GENERAL_ERROR) { + ret = -4; + break; + } + else if (rv == CKR_CANCEL) { ret = -3; break; } diff --git a/usr/bin/cryptosmartcard.sh b/usr/bin/cryptosmartcard.sh index f7ca6d9..ac8c206 100755 --- a/usr/bin/cryptosmartcard.sh +++ b/usr/bin/cryptosmartcard.sh @@ -80,6 +80,9 @@ msg () # flag tracking key-file availability OPENED=$FALSE +# Terminate the PC/SC subsystem +killall -9 pcscd > /dev/null 2>&1 || true + # Is the USB driver loaded? cat /proc/modules | busybox grep usb_storage >/dev/null 2>&1 USBLOAD=0$? @@ -88,11 +91,8 @@ if [ $USBLOAD -gt 0 ]; then modprobe usb_storage >/dev/null 2>&1 fi -# Terminate the PC/SC subsystem -killall pcscd > /dev/null 2>&1 || true - -# Give the system time to settle and open the USB devices -sleep 5 +# Make sure USB device nodes have loaded +udevadm settle # Relaunch the PC/SC subsystem pcscd > /dev/null 2>&1 @@ -114,6 +114,35 @@ if [ $LUKS_KEY_COUNT -gt 0 ]; then # Card present CARD_INSERTED=$TRUE msg "SmartCard inserted, attempting to authenticate" + + if [ -e /dev/kmsg ]; then + # Linux specific! + # Wait for nonblocking random driver to start. + # Without waiting, the pincheck utility can stall + # for a very long time (forever?) waiting + # for enough random data to start PKCS11. + dmesg | grep -q "random: nonblocking pool is initialized" &> /dev/null + RET=$? + LOOPS=0 + if [ $RET -ne 0 ]; then + msg "Waiting for nonblocking random pool to start..." + sleep 1 + while [ $RET -ne 0 ]; do + dmesg | grep -q "random: nonblocking pool is initialized" &> /dev/null + RET=$? + if [ $RET -ne 0 ]; then + sleep 1 + LOOPS=$((LOOPS+1)) + if [ $LOOPS -eq 10 ]; then + msg "Random pool initialization is slow. Try pressing keys or moving the mouse to speed it up..." + fi + fi + done + msg "Nonblocking pool started, continuing!" + fi + rm -f /tmp/kmsg + fi + PIN=$(cardpincheck /usr/lib/opensc-pkcs11.so) RET=$? if [ $RET -eq 0 ]; then @@ -135,7 +164,7 @@ if [ $LUKS_KEY_COUNT -gt 0 ]; then fi fi -killall pcscd > /dev/null 2>&1 || true +killall -9 pcscd > /dev/null 2>&1 || true if [ $OPENED -eq $FALSE ]; then if [ $CARD_INSERTED -eq $TRUE ]; then