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) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to