aboutsummaryrefslogtreecommitdiffstats
path: root/sbin/gbde
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2006-02-08 06:52:15 +0000
committerColin Percival <cperciva@FreeBSD.org>2006-02-08 06:52:15 +0000
commit6d118bffe747f0f0aa44039ae727b0497ab6fcbb (patch)
treea9d91a4aef336ec1fe63a8775d2c0f15dd851482 /sbin/gbde
parentc68a0f14fd5bc73d9c07392b321b3a41bcabc0ac (diff)
downloadsrc-6d118bffe747f0f0aa44039ae727b0497ab6fcbb.tar.gz
src-6d118bffe747f0f0aa44039ae727b0497ab6fcbb.zip
Teach gbde(8) to use a key file in addition to a passphrase. This
makes it practical to use GBDE for "something you have plus something you know" security together with a USB flash drive. Reviewed by: phk MFC after: 7 days
Notes
Notes: svn path=/head/; revision=155453
Diffstat (limited to 'sbin/gbde')
-rw-r--r--sbin/gbde/gbde.824
-rw-r--r--sbin/gbde/gbde.c86
2 files changed, 85 insertions, 25 deletions
diff --git a/sbin/gbde/gbde.8 b/sbin/gbde/gbde.8
index fe3d55d98728..d9994ea2ecbb 100644
--- a/sbin/gbde/gbde.8
+++ b/sbin/gbde/gbde.8
@@ -41,6 +41,7 @@
.Nm
.Cm attach
.Ar destination
+.Op Fl k Ar keyfile
.Op Fl l Ar lockfile
.Op Fl p Ar pass-phrase
.Nm
@@ -51,25 +52,30 @@
.Ar destination
.Op Fl i
.Op Fl f Ar filename
+.Op Fl K Ar new-keyfile
.Op Fl L Ar new-lockfile
.Op Fl P Ar new-pass-phrase
.Nm
.Cm setkey
.Ar destination
.Op Fl n Ar key
+.Op Fl k Ar keyfile
.Op Fl l Ar lockfile
.Op Fl p Ar pass-phrase
+.Op Fl K Ar new-keyfile
.Op Fl L Ar new-lockfile
.Op Fl P Ar new-pass-phrase
.Nm
.Cm nuke
.Ar destination
.Op Fl n Ar key
+.Op Fl k Ar keyfile
.Op Fl l Ar lockfile
.Op Fl p Ar pass-phrase
.Nm
.Cm destroy
.Ar destination
+.Op Fl k Ar keyfile
.Op Fl l Ar lockfile
.Op Fl p Ar pass-phrase
.Sh DESCRIPTION
@@ -180,6 +186,24 @@ Be aware that using this option may expose the pass-phrase to other
users who happen to run
.Xr ps 1
or similar while the command is running.
+.Pp
+The
+.Fl k Ar keyfile
+argument specifies a key file to be used in combination with the
+pass-phrase (whether the pass-phrase is specified on the command line
+or entered from the terminal) for opening the device.
+The device will only be opened if the contents of the key file and the
+pass-phrase are both correct.
+.Pp
+The
+.Fl K Ar new-keyfile
+argument can be used to specify a new key file to the
+.Cm init
+and
+.Cm setkey
+subcommands.
+If not specified, no key file will be used (even if one was previously
+used).
.Sh EXAMPLES
To initialize a device, using default parameters:
.Pp
diff --git a/sbin/gbde/gbde.c b/sbin/gbde/gbde.c
index 00c8e1c3fc94..0a1e740c4041 100644
--- a/sbin/gbde/gbde.c
+++ b/sbin/gbde/gbde.c
@@ -134,14 +134,16 @@ usage(void)
{
(void)fprintf(stderr,
-"usage: gbde attach destination [-l lockfile] [-p pass-phrase]\n"
+"usage: gbde attach destination [-k keyfile] [-l lockfile] [-p pass-phrase]\n"
" gbde detach destination\n"
-" gbde init destination [-i] [-f filename] [-L new-lockfile]\n"
-" [-P new-pass-phrase]\n"
-" gbde setkey destination [-n key] [-l lockfile] [-p pass-phrase]\n"
+" gbde init destination [-i] [-f filename] [-K new-keyfile]\n"
" [-L new-lockfile] [-P new-pass-phrase]\n"
-" gbde nuke destination [-n key] [-l lockfile] [-p pass-phrase]\n"
-" gbde destroy destination [-l lockfile] [-p pass-phrase]\n");
+" gbde setkey destination [-n key]\n"
+" [-k keyfile] [-l lockfile] [-p pass-phrase]\n"
+" [-K new-keyfile] [-L new-lockfile] [-P new-pass-phrase]\n"
+" gbde nuke destination [-n key]\n"
+" [-k keyfile] [-l lockfile] [-p pass-phrase]\n"
+" gbde destroy destination [-k keyfile] [-l lockfile] [-p pass-phrase]\n");
exit(1);
}
@@ -195,42 +197,67 @@ reset_passphrase(struct g_bde_softc *sc)
}
static void
-setup_passphrase(struct g_bde_softc *sc, int sure, const char *input)
+setup_passphrase(struct g_bde_softc *sc, int sure, const char *input,
+ const char *keyfile)
{
- char buf1[BUFSIZ], buf2[BUFSIZ], *p;
+ char buf1[BUFSIZ + SHA512_DIGEST_LENGTH];
+ char buf2[BUFSIZ + SHA512_DIGEST_LENGTH];
+ char *p;
+ int kfd, klen, bpos = 0;
+
+ if (keyfile != NULL) {
+ /* Read up to BUFSIZ bytes from keyfile */
+ kfd = open(keyfile, O_RDONLY, 0);
+ if (kfd < 0)
+ err(1, "%s", keyfile);
+ klen = read(kfd, buf1, BUFSIZ);
+ if (klen == -1)
+ err(1, "%s", keyfile);
+ close(kfd);
+
+ /* Prepend the passphrase with the hash of the key read */
+ g_bde_hash_pass(sc, buf1, klen);
+ memcpy(buf1, sc->sha2, SHA512_DIGEST_LENGTH);
+ memcpy(buf2, sc->sha2, SHA512_DIGEST_LENGTH);
+ bpos = SHA512_DIGEST_LENGTH;
+ }
if (input != NULL) {
- g_bde_hash_pass(sc, input, strlen(input));
+ if (strlen(input) >= BUFSIZ)
+ errx(1, "Passphrase too long");
+ strcpy(buf1 + bpos, input);
+
+ g_bde_hash_pass(sc, buf1, strlen(buf1 + bpos) + bpos);
memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH);
return;
}
for (;;) {
p = readpassphrase(
sure ? "Enter new passphrase:" : "Enter passphrase: ",
- buf1, sizeof buf1,
+ buf1 + bpos, sizeof buf1 - bpos,
RPP_ECHO_OFF | RPP_REQUIRE_TTY);
if (p == NULL)
err(1, "readpassphrase");
if (sure) {
p = readpassphrase("Reenter new passphrase: ",
- buf2, sizeof buf2,
+ buf2 + bpos, sizeof buf2 - bpos,
RPP_ECHO_OFF | RPP_REQUIRE_TTY);
if (p == NULL)
err(1, "readpassphrase");
- if (strcmp(buf1, buf2)) {
+ if (strcmp(buf1 + bpos, buf2 + bpos)) {
printf("They didn't match.\n");
continue;
}
}
- if (strlen(buf1) < 3) {
+ if (strlen(buf1 + bpos) < 3) {
printf("Too short passphrase.\n");
continue;
}
break;
}
- g_bde_hash_pass(sc, buf1, strlen(buf1));
+ g_bde_hash_pass(sc, buf1, strlen(buf1 + bpos) + bpos);
memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH);
}
@@ -708,6 +735,7 @@ int
main(int argc, char **argv)
{
const char *opts;
+ const char *k_opt, *K_opt;
const char *l_opt, *L_opt;
const char *p_opt, *P_opt;
const char *f_opt;
@@ -730,26 +758,26 @@ main(int argc, char **argv)
doopen = 0;
if (!strcmp(argv[1], "attach")) {
action = ACT_ATTACH;
- opts = "l:p:";
+ opts = "k:l:p:";
} else if (!strcmp(argv[1], "detach")) {
action = ACT_DETACH;
opts = "";
} else if (!strcmp(argv[1], "init")) {
action = ACT_INIT;
doopen = 1;
- opts = "f:iL:P:";
+ opts = "f:iK:L:P:";
} else if (!strcmp(argv[1], "setkey")) {
action = ACT_SETKEY;
doopen = 1;
- opts = "l:L:n:p:P:";
+ opts = "k:K:l:L:n:p:P:";
} else if (!strcmp(argv[1], "destroy")) {
action = ACT_DESTROY;
doopen = 1;
- opts = "l:p:";
+ opts = "k:l:p:";
} else if (!strcmp(argv[1], "nuke")) {
action = ACT_NUKE;
doopen = 1;
- opts = "l:n:p:";
+ opts = "k:l:n:p:";
} else {
usage();
}
@@ -762,6 +790,8 @@ main(int argc, char **argv)
p_opt = NULL;
P_opt = NULL;
+ k_opt = NULL;
+ K_opt = NULL;
l_opt = NULL;
L_opt = NULL;
f_opt = NULL;
@@ -775,6 +805,12 @@ main(int argc, char **argv)
break;
case 'i':
i_opt = !i_opt;
+ case 'k':
+ k_opt = optarg;
+ break;
+ case 'K':
+ K_opt = optarg;
+ break;
case 'l':
l_opt = optarg;
break;
@@ -819,7 +855,7 @@ main(int argc, char **argv)
gl = &sc.key;
switch(action) {
case ACT_ATTACH:
- setup_passphrase(&sc, 0, p_opt);
+ setup_passphrase(&sc, 0, p_opt, k_opt);
cmd_attach(&sc, dest, l_opt);
break;
case ACT_DETACH:
@@ -827,26 +863,26 @@ main(int argc, char **argv)
break;
case ACT_INIT:
cmd_init(gl, dfd, f_opt, i_opt, L_opt);
- setup_passphrase(&sc, 1, P_opt);
+ setup_passphrase(&sc, 1, P_opt, K_opt);
cmd_write(gl, &sc, dfd, 0, L_opt);
break;
case ACT_SETKEY:
- setup_passphrase(&sc, 0, p_opt);
+ setup_passphrase(&sc, 0, p_opt, k_opt);
cmd_open(&sc, dfd, l_opt, &nkey);
if (n_opt == 0)
n_opt = nkey + 1;
- setup_passphrase(&sc, 1, P_opt);
+ setup_passphrase(&sc, 1, P_opt, K_opt);
cmd_write(gl, &sc, dfd, n_opt - 1, L_opt);
break;
case ACT_DESTROY:
- setup_passphrase(&sc, 0, p_opt);
+ setup_passphrase(&sc, 0, p_opt, k_opt);
cmd_open(&sc, dfd, l_opt, &nkey);
cmd_destroy(gl, nkey);
reset_passphrase(&sc);
cmd_write(gl, &sc, dfd, nkey, l_opt);
break;
case ACT_NUKE:
- setup_passphrase(&sc, 0, p_opt);
+ setup_passphrase(&sc, 0, p_opt, k_opt);
cmd_open(&sc, dfd, l_opt, &nkey);
if (n_opt == 0)
n_opt = nkey + 1;