From owner-freebsd-geom@FreeBSD.ORG Sun Apr 27 09:55:47 2014 Return-Path: Delivered-To: freebsd-geom@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 306A7137 for ; Sun, 27 Apr 2014 09:55:47 +0000 (UTC) Received: from mail.cyberleo.net (mtumishi.cyberleo.net [216.226.128.201]) by mx1.freebsd.org (Postfix) with ESMTP id 0BE4122A for ; Sun, 27 Apr 2014 09:55:46 +0000 (UTC) Received: from [172.16.44.4] (vitani.den.cyberleo.net [216.80.73.130]) by mail.cyberleo.net (Postfix) with ESMTPSA id 715416973; Sun, 27 Apr 2014 05:55:33 -0400 (EDT) Message-ID: <535CD41A.5060104@cyberleo.net> Date: Sun, 27 Apr 2014 04:55:38 -0500 From: CyberLeo Kitsana User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: FreeBSD Geom Subject: Unlocking GELI at boot X-Enigmail-Version: 1.6 Content-Type: multipart/mixed; boundary="------------040205060200000107040306" X-BeenThere: freebsd-geom@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: GEOM-specific discussions and implementations List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Apr 2014 09:55:47 -0000 This is a multi-part message in MIME format. --------------040205060200000107040306 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi! I'm trying to set up a GELI-encrypted root using a keyfile to unlock during boot, but I'm running into an issue with the boot-time unlock when an eli container has a keyfile in keyslot 0 and an escrow passphrase in keyslot 1. I labeled a disk with ELI metadata in 10.0-RELEASE and configured it with the boot flag and a keyfile. When I added the keyfile to loader.conf, everything worked as expected. Next, I added a passphrase to the second keyslot of the encrypted root container. When I did this, I discovered that it was now impossible to unlock the container during boot as long as the keyfile was preloaded. A dip through the relevant kernel code suggests that if ANY slot has ever contained a passphrase (and thus md_iterations is not -1), it will always prompt for a passphrase and combine it with the preloaded keyfiles, resulting in a failure to unlock in this circumstance. I've hacked in a few bits of logic to the g_eli driver[1] to cause it to attempt an unlock using only the keyfiles on the first try, and only upon failure does it ask for a passphrase; this seems to correct the behaviour, but I'm wondering if this is really the best way to attack the issue. Thoughts? [1] http://pb.cyberleo.net/m54aca09a -- Fuzzy love, -CyberLeo Technical Administrator CyberLeo.Net Webhosting http://www.CyberLeo.Net Furry Peace! - http://www.fur.com/peace/ --------------040205060200000107040306 Content-Type: text/x-patch; name="g_eli.c-try_keyfiles_first.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="g_eli.c-try_keyfiles_first.patch" diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 18e3cc4..16cc0b9 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -1062,7 +1062,8 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) tries = 1; } else { /* Ask for the passphrase no more than g_eli_tries times. */ - tries = g_eli_tries; + /* CyberLeo: Add one to test first without password. */ + tries = g_eli_tries + 1; } for (i = 0; i < tries; i++) { @@ -1088,7 +1089,8 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) } /* Ask for the passphrase if defined. */ - if (md.md_iterations >= 0) { + /* CyberLeo: Don't ask if this is the first try */ + if (i > 0 && md.md_iterations >= 0) { printf("Enter passphrase for %s: ", pp->name); cngets(passphrase, sizeof(passphrase), g_eli_visible_passphrase); @@ -1096,14 +1098,15 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) /* * Prepare Derived-Key from the user passphrase. + * CyberLeo: But only after the first try. */ - if (md.md_iterations == 0) { + if (i > 0 && md.md_iterations == 0) { g_eli_crypto_hmac_update(&ctx, md.md_salt, sizeof(md.md_salt)); g_eli_crypto_hmac_update(&ctx, passphrase, strlen(passphrase)); bzero(passphrase, sizeof(passphrase)); - } else if (md.md_iterations > 0) { + } else if (i > 0 && md.md_iterations > 0) { u_char dkey[G_ELI_USERKEYLEN]; pkcs5v2_genkey(dkey, sizeof(dkey), md.md_salt, --------------040205060200000107040306--