Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Sep 2014 00:43:19 +0000 (UTC)
From:      Colin Percival <cperciva@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r272006 - stable/10/sys/geom/eli
Message-ID:  <201409230043.s8N0hJgZ025392@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cperciva
Date: Tue Sep 23 00:43:18 2014
New Revision: 272006
URL: http://svnweb.freebsd.org/changeset/base/272006

Log:
  MFC r271664:
    Cache GELI passphrases entered at the console during the boot process,
    in order to improve user-friendliness when a system has multiple disks
    encrypted using the same passphrase.
  
  Relnotes:	yes
  Approved by:	re (gjb)

Modified:
  stable/10/sys/geom/eli/g_eli.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/geom/eli/g_eli.c
==============================================================================
--- stable/10/sys/geom/eli/g_eli.c	Mon Sep 22 22:38:54 2014	(r272005)
+++ stable/10/sys/geom/eli/g_eli.c	Tue Sep 23 00:43:18 2014	(r272006)
@@ -88,6 +88,24 @@ TUNABLE_INT("kern.geom.eli.batch", &g_el
 SYSCTL_UINT(_kern_geom_eli, OID_AUTO, batch, CTLFLAG_RW, &g_eli_batch, 0,
     "Use crypto operations batching");
 
+/*
+ * Passphrase cached during boot, in order to be more user-friendly if
+ * there are multiple providers using the same passphrase.
+ */
+static char cached_passphrase[256];
+static u_int g_eli_boot_passcache = 1;
+TUNABLE_INT("kern.geom.eli.boot_passcache", &g_eli_boot_passcache);
+SYSCTL_UINT(_kern_geom_eli, OID_AUTO, boot_passcache, CTLFLAG_RD,
+    &g_eli_boot_passcache, 0,
+    "Passphrases are cached during boot process for possible reuse");
+static void
+zero_boot_passcache(void * dummy)
+{
+
+	memset(cached_passphrase, 0, sizeof(cached_passphrase));
+}
+EVENTHANDLER_DEFINE(mountroot, zero_boot_passcache, NULL, 0);
+
 static eventhandler_tag g_eli_pre_sync = NULL;
 
 static int g_eli_destroy_geom(struct gctl_req *req, struct g_class *mp,
@@ -1065,7 +1083,7 @@ g_eli_taste(struct g_class *mp, struct g
 		tries = g_eli_tries;
 	}
 
-	for (i = 0; i < tries; i++) {
+	for (i = 0; i <= tries; i++) {
 		g_eli_crypto_hmac_init(&ctx, NULL, 0);
 
 		/*
@@ -1089,9 +1107,19 @@ g_eli_taste(struct g_class *mp, struct g
 
 		/* Ask for the passphrase if defined. */
 		if (md.md_iterations >= 0) {
-			printf("Enter passphrase for %s: ", pp->name);
-			cngets(passphrase, sizeof(passphrase),
-			    g_eli_visible_passphrase);
+			/* Try first with cached passphrase. */
+			if (i == 0) {
+				if (!g_eli_boot_passcache)
+					continue;
+				memcpy(passphrase, cached_passphrase,
+				    sizeof(passphrase));
+			} else {
+				printf("Enter passphrase for %s: ", pp->name);
+				cngets(passphrase, sizeof(passphrase),
+				    g_eli_visible_passphrase);
+				memcpy(cached_passphrase, passphrase,
+				    sizeof(passphrase));
+			}
 		}
 
 		/*
@@ -1121,15 +1149,18 @@ g_eli_taste(struct g_class *mp, struct g
 		error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
 		bzero(key, sizeof(key));
 		if (error == -1) {
-			if (i == tries - 1) {
+			if (i == tries) {
 				G_ELI_DEBUG(0,
 				    "Wrong key for %s. No tries left.",
 				    pp->name);
 				g_eli_keyfiles_clear(pp->name);
 				return (NULL);
 			}
-			G_ELI_DEBUG(0, "Wrong key for %s. Tries left: %u.",
-			    pp->name, tries - i - 1);
+			if (i > 0) {
+				G_ELI_DEBUG(0,
+				    "Wrong key for %s. Tries left: %u.",
+				    pp->name, tries - i);
+			}
 			/* Try again. */
 			continue;
 		} else if (error > 0) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409230043.s8N0hJgZ025392>