svn commit: r271664 - head/sys/geom/eli
Colin Percival
cperciva at FreeBSD.org
Tue Sep 16 08:40:53 UTC 2014
Author: cperciva
Date: Tue Sep 16 08:40:52 2014
New Revision: 271664
URL: http://svnweb.freebsd.org/changeset/base/271664
Log:
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.
When examining a new GELI provider, the most recently used passphrase
will be attempted before prompting for a passphrase; and whenever a
passphrase is entered, it is cached for later reference. When the root
disk is mounted, the cached passphrase is zeroed (triggered by the
"mountroot" event), in order to minimize the possibility of leakage
of passphrases. (After root is mounted, the "taste and prompt for
passphrases on the console" code path is disabled, so there is no
potential for a passphrase to be stored after the zeroing takes place.)
This behaviour can be disabled by setting kern.geom.eli.boot_passcache=0.
Reviewed by: pjd, dteske, allanjude
MFC after: 7 days
Modified:
head/sys/geom/eli/g_eli.c
Modified: head/sys/geom/eli/g_eli.c
==============================================================================
--- head/sys/geom/eli/g_eli.c Tue Sep 16 05:45:38 2014 (r271663)
+++ head/sys/geom/eli/g_eli.c Tue Sep 16 08:40:52 2014 (r271664)
@@ -82,6 +82,24 @@ u_int g_eli_batch = 0;
SYSCTL_UINT(_kern_geom_eli, OID_AUTO, batch, CTLFLAG_RWTUN, &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,
@@ -1059,7 +1077,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);
/*
@@ -1083,9 +1101,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));
+ }
}
/*
@@ -1115,15 +1143,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) {
More information about the svn-src-head
mailing list