Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Aug 2017 14:07:24 +0000 (UTC)
From:      Mariusz Zaborski <oshogbo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r322923 - in head: . sbin/geom/class/eli sys/boot/geli sys/geom/eli
Message-ID:  <201708261407.v7QE7OtM093426@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oshogbo
Date: Sat Aug 26 14:07:24 2017
New Revision: 322923
URL: https://svnweb.freebsd.org/changeset/base/322923

Log:
  Hide length of geli passphrase during boot.
  
  Introduce additional flag to the geli which allows to restore previous
  behavior.
  
  Reviewed by:	AllanJude@, cem@ (previous version)
  MFC:		1 month
  Relnotes:	yes
  Differential Revision:	https://reviews.freebsd.org/D11751

Modified:
  head/UPDATING
  head/sbin/geom/class/eli/geli.8
  head/sbin/geom/class/eli/geom_eli.c
  head/sys/boot/geli/geliboot.c
  head/sys/boot/geli/geliboot.h
  head/sys/boot/geli/pwgets.c
  head/sys/geom/eli/g_eli.c
  head/sys/geom/eli/g_eli.h
  head/sys/geom/eli/g_eli_ctl.c

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/UPDATING	Sat Aug 26 14:07:24 2017	(r322923)
@@ -51,6 +51,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
 
 ****************************** SPECIAL WARNING: ******************************
 
+20170826:
+       During boot the geli passphrase will be hidden. To restore previous
+       behavior see geli(8) configuration options.
+
 20170825:
 	Move PMTUD blackhole counters to TCPSTATS and remove them from bare
 	sysctl values.  Minor nit, but requires a rebuild of both world/kernel

Modified: head/sbin/geom/class/eli/geli.8
==============================================================================
--- head/sbin/geom/class/eli/geli.8	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sbin/geom/class/eli/geli.8	Sat Aug 26 14:07:24 2017	(r322923)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 3, 2016
+.Dd August 26, 2017
 .Dt GELI 8
 .Os
 .Sh NAME
@@ -51,7 +51,7 @@ utility:
 .Pp
 .Nm
 .Cm init
-.Op Fl bgPTv
+.Op Fl bdgPTv
 .Op Fl a Ar aalgo
 .Op Fl B Ar backupfile
 .Op Fl e Ar ealgo
@@ -88,7 +88,7 @@ utility:
 .Ar prov
 .Nm
 .Cm configure
-.Op Fl bBgGtT
+.Op Fl bBdDgGtT
 .Ar prov ...
 .Nm
 .Cm setkey
@@ -279,6 +279,9 @@ To inhibit backups, you can use
 .Pa none
 as the
 .Ar backupfile .
+.It Fl d
+While booting from this encrypted root filesystem enable visibility of
+passphrase length.
 .It Fl e Ar ealgo
 Encryption algorithm to use.
 Currently supported algorithms are:
@@ -490,6 +493,12 @@ For more information, see the description of the
 subcommand.
 .It Fl B
 Remove the BOOT flag from the given providers.
+.It Fl d
+While booting from this encrypted root filesystem enable visibility of
+passphrase length.
+.It Fl D
+While booting from this encrypted root filesystem disable visibility of
+passphrase length.
 .It Fl g
 Enable booting from this encrypted root filesystem.
 The boot loader prompts for the passphrase and loads

Modified: head/sbin/geom/class/eli/geom_eli.c
==============================================================================
--- head/sbin/geom/class/eli/geom_eli.c	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sbin/geom/class/eli/geom_eli.c	Sat Aug 26 14:07:24 2017	(r322923)
@@ -82,7 +82,7 @@ static int eli_backup_create(struct gctl_req *req, con
 /*
  * Available commands:
  *
- * init [-bgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov
+ * init [-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov
  * label - alias for 'init'
  * attach [-dprv] [-j passfile] [-k keyfile] prov
  * detach [-fl] prov ...
@@ -107,6 +107,7 @@ struct g_command class_commands[] = {
 		{ 'a', "aalgo", "", G_TYPE_STRING },
 		{ 'b', "boot", NULL, G_TYPE_BOOL },
 		{ 'B', "backupfile", "", G_TYPE_STRING },
+		{ 'd', "displaypass", NULL, G_TYPE_BOOL },
 		{ 'e', "ealgo", "", G_TYPE_STRING },
 		{ 'g', "geliboot", NULL, G_TYPE_BOOL },
 		{ 'i', "iterations", "-1", G_TYPE_NUMBER },
@@ -119,13 +120,14 @@ struct g_command class_commands[] = {
 		{ 'V', "mdversion", "-1", G_TYPE_NUMBER },
 		G_OPT_SENTINEL
 	    },
-	    "[-bgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov"
+	    "[-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov"
 	},
 	{ "label", G_FLAG_VERBOSE, eli_main,
 	    {
 		{ 'a', "aalgo", "", G_TYPE_STRING },
 		{ 'b', "boot", NULL, G_TYPE_BOOL },
 		{ 'B', "backupfile", "", G_TYPE_STRING },
+		{ 'd', "displaypass", NULL, G_TYPE_BOOL },
 		{ 'e', "ealgo", "", G_TYPE_STRING },
 		{ 'g', "geliboot", NULL, G_TYPE_BOOL },
 		{ 'i', "iterations", "-1", G_TYPE_NUMBER },
@@ -182,13 +184,15 @@ struct g_command class_commands[] = {
 	    {
 		{ 'b', "boot", NULL, G_TYPE_BOOL },
 		{ 'B', "noboot", NULL, G_TYPE_BOOL },
+		{ 'd', "displaypass", NULL, G_TYPE_BOOL },
+		{ 'D', "nodisplaypass", NULL, G_TYPE_BOOL },
 		{ 'g', "geliboot", NULL, G_TYPE_BOOL },
 		{ 'G', "nogeliboot", NULL, G_TYPE_BOOL },
 		{ 't', "trim", NULL, G_TYPE_BOOL },
 		{ 'T', "notrim", NULL, G_TYPE_BOOL },
 		G_OPT_SENTINEL
 	    },
-	    "[-bBgGtT] prov ..."
+	    "[-bBdDgGtT] prov ..."
 	},
 	{ "setkey", G_FLAG_VERBOSE, eli_main,
 	    {
@@ -708,6 +712,8 @@ eli_init(struct gctl_req *req)
 		md.md_flags |= G_ELI_FLAG_BOOT;
 	if (gctl_get_int(req, "geliboot"))
 		md.md_flags |= G_ELI_FLAG_GELIBOOT;
+	if (gctl_get_int(req, "displaypass"))
+		md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
 	if (gctl_get_int(req, "notrim"))
 		md.md_flags |= G_ELI_FLAG_NODELETE;
 	md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
@@ -912,7 +918,7 @@ eli_attach(struct gctl_req *req)
 
 static void
 eli_configure_detached(struct gctl_req *req, const char *prov, int boot,
- int geliboot, int trim)
+    int geliboot, int displaypass, int trim)
 {
 	struct g_eli_metadata md;
 	bool changed = 0;
@@ -948,6 +954,21 @@ eli_configure_detached(struct gctl_req *req, const cha
 		changed = 1;
 	}
 
+	if (displaypass == 1 && (md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
+		if (verbose)
+			printf("GELIDISPLAYPASS flag already configured for %s.\n", prov);
+	} else if (displaypass == 0 &&
+	    !(md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
+		if (verbose)
+			printf("GELIDISPLAYPASS flag not configured for %s.\n", prov);
+	} else if (displaypass >= 0) {
+		if (displaypass)
+			md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
+		else
+			md.md_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
+		changed = 1;
+	}
+
 	if (trim == 0 && (md.md_flags & G_ELI_FLAG_NODELETE)) {
 		if (verbose)
 			printf("TRIM disable flag already configured for %s.\n", prov);
@@ -971,8 +992,9 @@ static void
 eli_configure(struct gctl_req *req)
 {
 	const char *prov;
-	bool boot, noboot, geliboot, nogeliboot, trim, notrim;
-	int doboot, dogeliboot, dotrim;
+	bool boot, noboot, geliboot, nogeliboot, displaypass, nodisplaypass;
+	bool trim, notrim;
+	int doboot, dogeliboot, dodisplaypass, dotrim;
 	int i, nargs;
 
 	nargs = gctl_get_int(req, "nargs");
@@ -985,6 +1007,8 @@ eli_configure(struct gctl_req *req)
 	noboot = gctl_get_int(req, "noboot");
 	geliboot = gctl_get_int(req, "geliboot");
 	nogeliboot = gctl_get_int(req, "nogeliboot");
+	displaypass = gctl_get_int(req, "displaypass");
+	nodisplaypass = gctl_get_int(req, "nodisplaypass");
 	trim = gctl_get_int(req, "trim");
 	notrim = gctl_get_int(req, "notrim");
 
@@ -1008,6 +1032,16 @@ eli_configure(struct gctl_req *req)
 	else if (nogeliboot)
 		dogeliboot = 0;
 
+	dodisplaypass = -1;
+	if (displaypass && nodisplaypass) {
+		gctl_error(req, "Options -d and -D are mutually exclusive.");
+		return;
+	}
+	if (displaypass)
+		dodisplaypass = 1;
+	else if (nodisplaypass)
+		dodisplaypass = 0;
+
 	dotrim = -1;
 	if (trim && notrim) {
 		gctl_error(req, "Options -t and -T are mutually exclusive.");
@@ -1018,7 +1052,8 @@ eli_configure(struct gctl_req *req)
 	else if (notrim)
 		dotrim = 0;
 
-	if (doboot == -1 && dogeliboot == -1 && dotrim == -1) {
+	if (doboot == -1 && dogeliboot == -1 && dodisplaypass == -1 &&
+	    dotrim == -1) {
 		gctl_error(req, "No option given.");
 		return;
 	}
@@ -1028,8 +1063,10 @@ eli_configure(struct gctl_req *req)
 	/* Now the rest. */
 	for (i = 0; i < nargs; i++) {
 		prov = gctl_get_ascii(req, "arg%d", i);
-		if (!eli_is_attached(prov))
-			eli_configure_detached(req, prov, doboot, dogeliboot, dotrim);
+		if (!eli_is_attached(prov)) {
+			eli_configure_detached(req, prov, doboot, dogeliboot,
+			    dodisplaypass, dotrim);
+		}
 	}
 }
 

Modified: head/sys/boot/geli/geliboot.c
==============================================================================
--- head/sys/boot/geli/geliboot.c	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sys/boot/geli/geliboot.c	Sat Aug 26 14:07:24 2017	(r322923)
@@ -220,8 +220,9 @@ geli_taste(int read_func(void *vdev, void *priv, off_t
 /*
  * Attempt to decrypt the device
  */
-int
-geli_attach(struct dsk *dskp, const char *passphrase, const u_char *mkeyp)
+static int
+geli_attach(struct geli_entry *ge, struct dsk *dskp, const char *passphrase,
+    const u_char *mkeyp)
 {
 	u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN], *mkp;
 	u_int keynum;
@@ -233,92 +234,83 @@ geli_attach(struct dsk *dskp, const char *passphrase, 
 		explicit_bzero(mkeyp, G_ELI_DATAIVKEYLEN);
 	}
 
-	SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
-		if (geli_same_device(geli_e, dskp) != 0) {
-			continue;
-		}
+	if (mkeyp != NULL || geli_findkey(ge, dskp, mkey) == 0) {
+		goto found_key;
+	}
 
-		if (mkeyp != NULL || geli_findkey(geli_e, dskp, mkey) == 0) {
-			goto found_key;
-		}
+	g_eli_crypto_hmac_init(&ctx, NULL, 0);
+	/*
+	 * Prepare Derived-Key from the user passphrase.
+	 */
+	if (geli_e->md.md_iterations < 0) {
+		/* XXX TODO: Support loading key files. */
+		return (1);
+	} else if (geli_e->md.md_iterations == 0) {
+		g_eli_crypto_hmac_update(&ctx, geli_e->md.md_salt,
+		    sizeof(geli_e->md.md_salt));
+		g_eli_crypto_hmac_update(&ctx, passphrase,
+		    strlen(passphrase));
+	} else if (geli_e->md.md_iterations > 0) {
+		printf("Calculating GELI Decryption Key disk%dp%d @ %d"
+		    " iterations...\n", dskp->unit,
+		    (dskp->slice > 0 ? dskp->slice : dskp->part),
+		    geli_e->md.md_iterations);
+		u_char dkey[G_ELI_USERKEYLEN];
 
-		g_eli_crypto_hmac_init(&ctx, NULL, 0);
-		/*
-		 * Prepare Derived-Key from the user passphrase.
-		 */
-		if (geli_e->md.md_iterations < 0) {
-			/* XXX TODO: Support loading key files. */
-			return (1);
-		} else if (geli_e->md.md_iterations == 0) {
-			g_eli_crypto_hmac_update(&ctx, geli_e->md.md_salt,
-			    sizeof(geli_e->md.md_salt));
-			g_eli_crypto_hmac_update(&ctx, passphrase,
-			    strlen(passphrase));
-		} else if (geli_e->md.md_iterations > 0) {
-			printf("Calculating GELI Decryption Key disk%dp%d @ %d"
-			    " iterations...\n", dskp->unit,
-			    (dskp->slice > 0 ? dskp->slice : dskp->part),
-			    geli_e->md.md_iterations);
-			u_char dkey[G_ELI_USERKEYLEN];
+		pkcs5v2_genkey(dkey, sizeof(dkey), geli_e->md.md_salt,
+		    sizeof(geli_e->md.md_salt), passphrase,
+		    geli_e->md.md_iterations);
+		g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
+		explicit_bzero(dkey, sizeof(dkey));
+	}
 
-			pkcs5v2_genkey(dkey, sizeof(dkey), geli_e->md.md_salt,
-			    sizeof(geli_e->md.md_salt), passphrase,
-			    geli_e->md.md_iterations);
-			g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
-			explicit_bzero(dkey, sizeof(dkey));
-		}
+	g_eli_crypto_hmac_final(&ctx, key, 0);
 
-		g_eli_crypto_hmac_final(&ctx, key, 0);
+	error = g_eli_mkey_decrypt(&geli_e->md, key, mkey, &keynum);
+	if (error == -1) {
+		explicit_bzero(mkey, sizeof(mkey));
+		explicit_bzero(key, sizeof(key));
+		printf("Bad GELI key: bad password?\n");
+		return (error);
+	} else if (error != 0) {
+		explicit_bzero(mkey, sizeof(mkey));
+		explicit_bzero(key, sizeof(key));
+		printf("Failed to decrypt GELI master key: %d\n", error);
+		return (error);
+	} else {
+		/* Add key to keychain */
+		save_key(key);
+		explicit_bzero(&key, sizeof(key));
+	}
 
-		error = g_eli_mkey_decrypt(&geli_e->md, key, mkey, &keynum);
-		if (error == -1) {
-			explicit_bzero(mkey, sizeof(mkey));
-			explicit_bzero(key, sizeof(key));
-			printf("Bad GELI key: bad password?\n");
-			return (error);
-		} else if (error != 0) {
-			explicit_bzero(mkey, sizeof(mkey));
-			explicit_bzero(key, sizeof(key));
-                        printf("Failed to decrypt GELI master key: %d\n", error);
-			return (error);
-		} else {
-                        /* Add key to keychain */
-                        save_key(key);
-                        explicit_bzero(&key, sizeof(key));
-                }
-
 found_key:
-		/* Store the keys */
-		bcopy(mkey, geli_e->sc.sc_mkey, sizeof(geli_e->sc.sc_mkey));
-		bcopy(mkey, geli_e->sc.sc_ivkey, sizeof(geli_e->sc.sc_ivkey));
-		mkp = mkey + sizeof(geli_e->sc.sc_ivkey);
-		if ((geli_e->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
-			bcopy(mkp, geli_e->sc.sc_ekey, G_ELI_DATAKEYLEN);
-		} else {
-			/*
-			 * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
-			 */
-			g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, "\x10", 1,
-			    geli_e->sc.sc_ekey, 0);
-		}
-		explicit_bzero(mkey, sizeof(mkey));
+	/* Store the keys */
+	bcopy(mkey, geli_e->sc.sc_mkey, sizeof(geli_e->sc.sc_mkey));
+	bcopy(mkey, geli_e->sc.sc_ivkey, sizeof(geli_e->sc.sc_ivkey));
+	mkp = mkey + sizeof(geli_e->sc.sc_ivkey);
+	if ((geli_e->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
+		bcopy(mkp, geli_e->sc.sc_ekey, G_ELI_DATAKEYLEN);
+	} else {
+		/*
+		 * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
+		 */
+		g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, "\x10", 1,
+		    geli_e->sc.sc_ekey, 0);
+	}
+	explicit_bzero(mkey, sizeof(mkey));
 
-		/* Initialize the per-sector IV. */
-		switch (geli_e->sc.sc_ealgo) {
-		case CRYPTO_AES_XTS:
-			break;
-		default:
-			SHA256_Init(&geli_e->sc.sc_ivctx);
-			SHA256_Update(&geli_e->sc.sc_ivctx, geli_e->sc.sc_ivkey,
-			    sizeof(geli_e->sc.sc_ivkey));
-			break;
-		}
-
-		return (0);
+	/* Initialize the per-sector IV. */
+	switch (geli_e->sc.sc_ealgo) {
+	case CRYPTO_AES_XTS:
+		break;
+	default:
+		SHA256_Init(&geli_e->sc.sc_ivctx);
+		SHA256_Update(&geli_e->sc.sc_ivctx, geli_e->sc.sc_ivkey,
+		    sizeof(geli_e->sc.sc_ivkey));
+		break;
 	}
 
-	/* Disk not found. */
-	return (2);
+	return (0);
 }
 
 int
@@ -402,7 +394,7 @@ geli_havekey(struct dsk *dskp)
 		}
 
 		if (geli_findkey(geli_e, dskp, mkey) == 0) {
-			if (geli_attach(dskp, NULL, mkey) == 0) {
+			if (geli_attach(geli_e, dskp, NULL, mkey) == 0) {
 				return (0);
 			}
 		}
@@ -417,19 +409,27 @@ geli_passphrase(char *pw, int disk, int parttype, int 
 {
 	int i;
 
-	/* TODO: Implement GELI keyfile(s) support */
-	for (i = 0; i < 3; i++) {
-		/* Try cached passphrase */
-		if (i == 0 && pw[0] != '\0') {
-			if (geli_attach(dskp, pw, NULL) == 0) {
+	SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
+		if (geli_same_device(geli_e, dskp) != 0) {
+			continue;
+		}
+
+		/* TODO: Implement GELI keyfile(s) support */
+		for (i = 0; i < 3; i++) {
+			/* Try cached passphrase */
+			if (i == 0 && pw[0] != '\0') {
+				if (geli_attach(geli_e, dskp, pw, NULL) == 0) {
+					return (0);
+				}
+			}
+			printf("GELI Passphrase for disk%d%c%d: ", disk,
+			    parttype, part);
+			pwgets(pw, GELI_PW_MAXLEN,
+			    (geli_e->md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS) == 0);
+			printf("\n");
+			if (geli_attach(geli_e, dskp, pw, NULL) == 0) {
 				return (0);
 			}
-		}
-		printf("GELI Passphrase for disk%d%c%d: ", disk, parttype, part);
-		pwgets(pw, GELI_PW_MAXLEN);
-		printf("\n");
-		if (geli_attach(dskp, pw, NULL) == 0) {
-			return (0);
 		}
 	}
 

Modified: head/sys/boot/geli/geliboot.h
==============================================================================
--- head/sys/boot/geli/geliboot.h	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sys/boot/geli/geliboot.h	Sat Aug 26 14:07:24 2017	(r322923)
@@ -46,12 +46,11 @@
 #define	GELI_MAX_KEYS			64
 #define GELI_PW_MAXLEN			256
 
-extern void pwgets(char *buf, int n);
+extern void pwgets(char *buf, int n, int hide);
 
 void geli_init(void);
 int geli_taste(int read_func(void *vdev, void *priv, off_t off,
     void *buf, size_t bytes), struct dsk *dsk, daddr_t lastsector);
-int geli_attach(struct dsk *dskp, const char *passphrase, const u_char *mkeyp);
 int is_geli(struct dsk *dsk);
 int geli_read(struct dsk *dsk, off_t offset, u_char *buf, size_t bytes);
 int geli_decrypt(u_int algo, u_char *data, size_t datasize,

Modified: head/sys/boot/geli/pwgets.c
==============================================================================
--- head/sys/boot/geli/pwgets.c	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sys/boot/geli/pwgets.c	Sat Aug 26 14:07:24 2017	(r322923)
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
 /* gets() with constrained input length, for passwords */
 
 void
-pwgets(char *buf, int n)
+pwgets(char *buf, int n, int hide)
 {
     int c;
     char *lp;
@@ -55,9 +55,11 @@ pwgets(char *buf, int n)
 	case '\177':
 	    if (lp > buf) {
 		lp--;
-		putchar('\b');
-		putchar(' ');
-		putchar('\b');
+		if (hide == 0) {
+			putchar('\b');
+			putchar(' ');
+			putchar('\b');
+		}
 	    }
 	    break;
 	case 'u'&037:
@@ -68,7 +70,9 @@ pwgets(char *buf, int n)
 	default:
 	    if ((n < 1) || ((lp - buf) < n - 1)) {
 		*lp++ = c;
-		putchar('*');
+		if (hide == 0) {
+			putchar('*');
+		}
 	    }
 	}
     /*NOTREACHED*/

Modified: head/sys/geom/eli/g_eli.c
==============================================================================
--- head/sys/geom/eli/g_eli.c	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sys/geom/eli/g_eli.c	Sat Aug 26 14:07:24 2017	(r322923)
@@ -1023,7 +1023,7 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp,
 	struct hmac_ctx ctx;
 	char passphrase[256];
 	u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN];
-	u_int i, nkey, nkeyfiles, tries;
+	u_int i, nkey, nkeyfiles, tries, showpass;
 	int error;
         struct keybuf *keybuf;
 
@@ -1112,8 +1112,11 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp,
                                     sizeof(passphrase));
                         } else {
                                 printf("Enter passphrase for %s: ", pp->name);
+				showpass = g_eli_visible_passphrase;
+				if ((md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS) != 0)
+					showpass = GETS_ECHOPASS;
                                 cngets(passphrase, sizeof(passphrase),
-                                    g_eli_visible_passphrase);
+				    showpass);
                                 memcpy(cached_passphrase, passphrase,
                                     sizeof(passphrase));
                         }
@@ -1232,6 +1235,7 @@ g_eli_dumpconf(struct sbuf *sb, const char *indent, st
 		ADD_FLAG(G_ELI_FLAG_RO, "READ-ONLY");
 		ADD_FLAG(G_ELI_FLAG_NODELETE, "NODELETE");
 		ADD_FLAG(G_ELI_FLAG_GELIBOOT, "GELIBOOT");
+		ADD_FLAG(G_ELI_FLAG_GELIDISPLAYPASS, "GELIDISPLAYPASS");
 #undef  ADD_FLAG
 	}
 	sbuf_printf(sb, "</Flags>\n");

Modified: head/sys/geom/eli/g_eli.h
==============================================================================
--- head/sys/geom/eli/g_eli.h	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sys/geom/eli/g_eli.h	Sat Aug 26 14:07:24 2017	(r322923)
@@ -100,6 +100,8 @@
 #define	G_ELI_FLAG_NODELETE		0x00000040
 /* This GELI supports GELIBoot */
 #define	G_ELI_FLAG_GELIBOOT		0x00000080
+/* Hide passphrase length in GELIboot. */
+#define	G_ELI_FLAG_GELIDISPLAYPASS	0x00000100
 /* RUNTIME FLAGS. */
 /* Provider was open for writing. */
 #define	G_ELI_FLAG_WOPEN		0x00010000

Modified: head/sys/geom/eli/g_eli_ctl.c
==============================================================================
--- head/sys/geom/eli/g_eli_ctl.c	Sat Aug 26 07:05:29 2017	(r322922)
+++ head/sys/geom/eli/g_eli_ctl.c	Sat Aug 26 14:07:24 2017	(r322923)
@@ -377,6 +377,7 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_cla
 	const char *prov;
 	u_char *sector;
 	int *nargs, *boot, *noboot, *trim, *notrim, *geliboot, *nogeliboot;
+	int *displaypass, *nodisplaypass;
 	int zero, error, changed;
 	u_int i;
 
@@ -434,6 +435,19 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_cla
 	if (*geliboot || *nogeliboot)
 		changed = 1;
 
+	displaypass = gctl_get_paraml(req, "displaypass", sizeof(*displaypass));
+	if (displaypass == NULL)
+		displaypass = &zero;
+	nodisplaypass = gctl_get_paraml(req, "nodisplaypass", sizeof(*nodisplaypass));
+	if (nodisplaypass == NULL)
+		nodisplaypass = &zero;
+	if (*displaypass && *nodisplaypass) {
+		gctl_error(req, "Options -d and -D are mutually exclusive.");
+		return;
+	}
+	if (*displaypass || *nodisplaypass)
+		changed = 1;
+
 	if (!changed) {
 		gctl_error(req, "No option given.");
 		return;
@@ -492,6 +506,17 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_cla
 			continue;
 		}
 
+		if (*displaypass && (sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
+			G_ELI_DEBUG(1, "GELIDISPLAYPASS flag already configured for %s.",
+			    prov);
+			continue;
+		} else if (*nodisplaypass &&
+		    !(sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
+			G_ELI_DEBUG(1, "GELIDISPLAYPASS flag not configured for %s.",
+			    prov);
+			continue;
+		}
+
 		if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) {
 			/*
 			 * ONETIME providers don't write metadata to
@@ -533,6 +558,14 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_cla
 		} else if (*nogeliboot) {
 			md.md_flags &= ~G_ELI_FLAG_GELIBOOT;
 			sc->sc_flags &= ~G_ELI_FLAG_GELIBOOT;
+		}
+
+		if (*displaypass) {
+			md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
+			sc->sc_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
+		} else if (*nodisplaypass) {
+			md.md_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
+			sc->sc_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
 		}
 
 		if (sc->sc_flags & G_ELI_FLAG_ONETIME) {



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