summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2014-09-23 00:43:18 +0000
committercperciva <cperciva@FreeBSD.org>2014-09-23 00:43:18 +0000
commit925d357775e209d38f38e7cc1d338269fd635cbb (patch)
tree9dd635a40066495cab472ce42c758c969f2cdf63 /sys/geom
parent66312b96c421785487810a818ec20e41c36f1751 (diff)
downloadFreeBSD-src-925d357775e209d38f38e7cc1d338269fd635cbb.zip
FreeBSD-src-925d357775e209d38f38e7cc1d338269fd635cbb.tar.gz
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)
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/eli/g_eli.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c
index d1f3cd2..01c3b53 100644
--- a/sys/geom/eli/g_eli.c
+++ b/sys/geom/eli/g_eli.c
@@ -88,6 +88,24 @@ TUNABLE_INT("kern.geom.eli.batch", &g_eli_batch);
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_provider *pp, int flags __unused)
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_provider *pp, int flags __unused)
/* 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_provider *pp, int flags __unused)
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) {
OpenPOWER on IntegriCloud