Relnotes: yes!

On 9/16/14, 3:40 AM, Colin Percival wrote:
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) {



--
Regards,
Bryan Drewery
_______________________________________________
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