diff options
author | cperciva <cperciva@FreeBSD.org> | 2014-09-23 00:43:18 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2014-09-23 00:43:18 +0000 |
commit | 925d357775e209d38f38e7cc1d338269fd635cbb (patch) | |
tree | 9dd635a40066495cab472ce42c758c969f2cdf63 /sys/geom | |
parent | 66312b96c421785487810a818ec20e41c36f1751 (diff) | |
download | FreeBSD-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.c | 45 |
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) { |