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
<[email protected]>

Furry Peace! - http://www.fur.com/peace/
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,
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-geom
To unsubscribe, send any mail to "[email protected]"

Reply via email to